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)
Rails 5 Action Cable CORS:
create a ruby file i.e action_cable.rb
in my_rails_project/config/initializers
and add the following code.
if Rails.env.development?
Rails.application.config.action_cable.allowed_request_origins = ['http://localhost:3001', 'http://127.0.0.1:3001']
end
you are done.
Have you set the config.action_cable.allowed_request_origins
in production.rb to allow connections from your production domain?
In my nginx.conf there is also
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto http;
I am not entirely sure if they are really required, but it works for me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With