3

I am using padrino websockets (https://github.com/dariocravero/padrino-websockets) to provide a chat system for my site, and it works great on my local machine. However, after deploying to heroku (free), the websocket won't make a connection and will return

failed: Connection closed before receiving a handshake response

It works fine on localhost, where I am using this to connect:

connection = new WebSocket('ws://localhost:3000/channel');

But, when used on heroku with this:

connection = new WebSocket('ws://******.herokuapp.com:3000/channel');

it returns a handshake error (above)

My implementation server side

websocket :channel do
  on :newmessage do |message|
    currentAccount = Account.find_by(lastLoginIP: message["ip"]) rescue nil

    if currentAccount != nil
      broadcast :channel, {
        "name" => currentAccount.nickname,
        "url" => currentAccount.url,
        "image" =>  currentAccount.image,
        "chatmessage" => message["chatmessage"][0..80]
        }
    end

  end
end

inside my main Padrino app.rb, and this in my Procfile. What is going on?

web: bundle exec puma -t 1:16 -p ${PORT:-3000} -e ${RACK_ENV:-production}
kRIST-
  • 186
  • 1
  • 7

1 Answers1

5

Your Websocket port (3000) isn't publicly available on Heroku.

Heroku forwards any requests made to port 80 or port 443 to the dynamic port of your web dyno, stored in the $PORT bash variable.

In your browser (client), try replacing this line:

 connection = new WebSocket('ws://localhost:3000/channel');

With this line:

 connection = new WebSocket('ws://' + window.document.location.host + 'channel');

Or, if you want to support both SSL and unencrypted Websockets:

 ws_uri = (window.location.protocol.match(/https/) ? 'wss' : 'ws') +
          '://' + window.document.location.host + 'channel';
 connection = new WebSocket(ws_uri)

It should work if both your app and the websocket layer are sharing the same server.

Myst
  • 18,516
  • 2
  • 45
  • 67