Search code examples
ruby-on-railsrubywebsocketpumaactioncable

ActionCable / Websocket not working with Puma


The problem

In development I'm having split processes between my Rails server and ActionCable.

➜  backend git:(dev) bundle exec puma cable/config.ru -p 1337
Puma starting in single mode...
* Version 3.12.0 (ruby 2.5.1-p57), codename: Llamas in Pajamas
* Min threads: 0, max threads: 16
* Environment: development

My configuration is pretty classical

# cable/config.ru
require_relative '../config/cable_environment'
Rails.application.eager_load!

run ActionCable.server

And in my development.rb I've got those

# Set Action Cable server url for consumer connection
config.action_cable.url = 'wss://localhost:4001'
config.action_cable.allowed_request_origins = [
  'https://localhost:4000',
]

It looks like it's working. In parallel of that I use some split front-end in VueJS to listen to the websockets. You should know this whole configuration was working before a few days back.

When I try to listen to sockets from the front-end it does this

action_cable.js?f5ee:241 WebSocket connection to 'wss://localhost:4001/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

What I know

The SSL is correctly configured (as I said it was actually working before) and the configuration seems really fine. I'm also not the only one working on this Rails project but the only one to face this issue.

When I try to check it the port is in use I do the following

lsof -ti:4001

I noticed no process is running at all and I've no idea how to troubleshoot this. As the websocket server seems to be intern to ActionCable, I don't really know how to search what crashes, there's no error displayed, puma is up and running, but the websockets aren't.

What I tried

I can't recollect exactly what I did in the last few days which could have broken the Websockets, so I tried many things

  • I've tried to change the configuration in many, many ways, but I pasted the original one here. Basically ran the whole documentation multiple times and tried all combinations i could think of
  • I've tried to change the port, or endpoint
  • I changed the SSL certificates which are self-hosted (and working) and produced new ones, it doesn't seem to be linked to the problem
  • I've tried to downgrade Puma but it didn't change anything.
  • I've tried to reinstall the project entirely in a fresh directory but it still doesn't work.
  • I've also reinstalled multiple times Ruby via RVM and tried a few versions, without success.
  • I even ended up upgrading my computer to MacOS Mojave in a desperate move, didn't move the problem one bit.

What I don't know

I don't know anything about the mechanism to spawn Websockets via ActionCable. Why isn't there any error ? How does it work ? Did I miss something in my configuration? Does it interact with anything else like NPM / Node / Apollo Which could have changed on my computer? I work on multiple projects with multiple technologies, it's pretty hard to find an exact origin ...

If you need more informations, just let me know. Thanks for your time.


Solution

  • The solution

    I figured I had an Nginx setup to make my sockets work with TLS which I had forgotten about. If you end up here, you may be in the same case.

    You can check that out by doing nginx -t in your console and open the file - if any present - in your IDE.

    # /usr/local/etc/nginx/nginx.conf
    ...
    server {
      listen   5212 ssl;
      server_name  localhost;
      ssl_certificate /Users/loschcode/Desktop/some-path/ssl/server.crt;
      ssl_certificate_key /Users/loschcode/Desktop/some-path/ssl/server.key;
    
      location / {
        rewrite ^(.*) https://localhost:5214$1 permanent;
      }
    }
    ...
    

    I recently changed the directory I used to work on the project, which made a wrong path to the certificate, therefore my issue. Fixing the path made it work.