I am having a issue in connecting to websocket in non-development environments with these log messages
Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: close, HTTP_UPGRADE: )
Finished "/cable/"[non-WebSocket] for 127.0.0.1 at 2016-07-06 09:44:29 +1000
I debuggged a little and figured out the request sent by the browser/javascript is not exactly the same as the request received by unicorn(running with nginx).
The request header by the browser is
GET ws://cc-uat.com.au/cable HTTP/1.1
Host: cc-uat.com.au
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://cc-uat.com.au
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Cookie: <Lot of cookies>
Sec-WebSocket-Key: QGdJkYIA2u7vtmMVXfHKtQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: actioncable-v1-json, actioncable-unsupported
The connection here is 'upgrade' but the websocket request has the connection 'closed'(probably nginx is messing it up?)
And this piece of code in websocket driver is failing
def self.websocket?(env)
connection = env['HTTP_CONNECTION'] || ''
upgrade = env['HTTP_UPGRADE'] || ''
env['REQUEST_METHOD'] == 'GET' and
connection.downcase.split(/ *, */).include?('upgrade') and
upgrade.downcase == 'websocket'
end
Updates
This is my nginx configuration
upstream app {
server unix:/home/osboxes/sites/actioncable-examples/shared/sockets/unicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name localhost;
root /home/osboxes/sites/actioncable-example/public;
try_files $uri/index.html $uri @app;
location @app {
proxy_pass http://app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
I have mounted actioncable server on /cable
mount ActionCable.server => "/cable"
With the nginx changes i am able to successfully have the handshake but the server is not able to send the heart beats and the connection keeps dropping.
Started GET "/cable" for 127.0.0.1 at 2016-07-07 05:48:06 +0100
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2016-07-07 05:48:06 +0100
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: upgrade, HTTP_UPGRADE: websocket)
Upgrade
andConnection
headers as nginx.com/blog/websocket-nginx suggests? – Maemaeanderconfig.action_cable.allowed_request_origins
. Also, if your app is running behind nginx proxy, you need to proxy_set_header as mentioned by @juliuszGonera. See also nginx.org/en/docs/http/websocket.html. – Arias