Rails, ActionCable and WebSockets

Hey there!

I’m trying to run a Rails application which aside from other functionality is also using WebSockets. Though I get an error when trying to connect to wss://my-domain.com (application hosted on render.com).
Do I have to do any specific configuration to allow this?

And by the way, there’s no Slack support anymore on Render.com?

Thank you!

Hello!

Web sockets should work without any configuration of Render’s settings. Can you share more details about the error you are seeing? Feel free to DM me if you’d prefer.

We have deprecated the Slack channel in favor of this community in order to build a more searchable knowledge base for users.

Thank you for replying Jake!

I’m trying to connect from a React app, this works locally and on my previous staging server (AWS) and it does not work on render.
The error I keep getting on the client app is this:

WebSocket connection to ‘wss://some-domain.com/cable?..’ failed: e.open @ 2.69d9521f.chunk.js:2

and the request does not hit the backend app, it’s somehow rejected before.

You probably already know that but there are some specific configs needed depending on the load balancers used or whatever is in front of our apps on render. On my AWS servers, the nginx config needs to include something like:

location /wsapp/ {
    proxy_pass http://wsbackend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header Host $host;
}

and on Apache, something like this:

<VirtualHost domain.of.the.rails-app:80>
    ServerName domain.of.the.rails-app
    DocumentRoot /var/www/apps/rails-app/public
    ProxyPreserveHost On
    ProxyPass /error-documents !
    ErrorDocument 503 /error-documents/503.html
    Alias /error-documents /var/www/apps/rails-app/public
    ProxyPass / http://0.0.0.0:3000/
    ProxyPassReverse / http://0.0.0.0:3000/
    RewriteEngine on
    RewriteCond %{HTTP:UPGRADE} websocket [NC]
    RewriteRule /(.*) ws://localhost:3000/$1 [P]
</VirtualHost>

so I’m not sure exactly what you guys use but there needs to be some specific configs in place to allow for web sockets.

Thanks again!

I’m running into some issues with ActionCable on Render as well. Although it could be because of my own code (it did work on my previous host however).

Would love to see a basic example in the render-examples repository of a working ActionCable project. Something I can host and compare my own implementation to.

( For reference, my project is https://expensive.chat but I’m currently working on it. So you might see some misconfiguration due to testing, etc. )

I’m getting the following error:

WebSocket connection to 'wss://expensive.chat/cable' failed: Unexpected response code: 301

Most results on Google and StackOverflow talk about nginx configuration. Which does suggest there might be something one Render’s side.

I think I’ve solved it by disabling force_ssl

I’m not sure why that’s needed. Maybe Render is doing something internally making Rails think the websocket connection is insecure so it tries to redirect.

3 Likes

That does make sense. Render forces SSL and automatically terminates it at the proxy, so your app receives an insecure request and returns a 301 when force_ssl is enabled.

1 Like

This fixed it for me also. Great find marc!

Thank you both!

1 Like

That makes sense. Thanks for the explanation.

I expect other people might run into this as well, as it’s common practice (and possibly even default behavior?) for Rails apps to have that setting enabled.

Not sure what you can do about it on Render’s site, but perhaps it’s worth adding a note in the docs.

3 Likes

I just wanted to say this worked for me too. Thanks!

For reference, in addition to config.force_ssl = false, I also have config.action_cable.url and config.action_cable.allowed_request_origins set in the production.rb file.