ActionCable wouldn't broadcast notification from sidekiq job, but works fine from console

Viewed 308

I'm trying to get up to speed on ActionCable and am having some issues getting messages to broadcast. My goal is straightforward: I have a sidekiq job running, and at the end of the job, I want to notify the front-end that the job is complete. I have reduced it down the the bare bone and it's still not working.

If I submit the broadcast command in console, everything works fine (i.e., message shows up in console), but not when it's called inside the sidekiq job. When I call NotificationBroadcastWorker.perform_async(user_id), the broadcast command returns nil. I have also made sure to update cable.yml to use redis in development per comments on this other thread. Maybe there's some other weird configuration issue. Any help would be appreciated. Thanks!

Below are my code snippets:

notification_broadcast_worker.rb

class NotificationBroadcastWorker
  include Sidekiq::Worker

  def perform(user_id)
    ActionCable.server.broadcast "notification_channel.#{user_id}", { action: "new_notification", message: "record was successfully updated" }
  end
end

notification_channel.rb

class NotificationChannel < ApplicationCable::Channel
  def subscribed
    # stream_from "some_channel"
    stream_from "notification_channel.#{current_user.id}"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end
end

notification_channel.js

import consumer from "./consumer"

consumer.subscriptions.create("NotificationChannel", {
  connected() {
    // Called when the subscription is ready for use on the server
    console.log("connected to notication channel")
  },

  disconnected() {
    // Called when the subscription has been terminated by the server
  },

  received(data) {
    // Called when there's incoming data on the websocket for this channel
    console.log(data)
  }
});

application_cable/connection.rb

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
    end

    private

    def find_verified_user
      if verified_user = env['warden'].user
        verified_user
      else
        reject_unauthorized_connection
      end
    end
  end
end

cable.yml

development:
  adapter: redis
  url: redis://localhost:6379/1

test:
  adapter: test

production:
  adapter: redis
  url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
  channel_prefix: oakheart_production
0 Answers
Related