ruby-on-railswebsocketactioncable

Rails - Action cable : Broadcasting to specific resource


I am using action cable and rails 6. I am trying to broadcast messages to a particular organization. My client js code picks up the organization id on the page an creates a subscription on the organization channel, passing up the organization_id.

const organizationID = document.getElementById("organization-wrapper").dataset.organizationId
  consumer.subscriptions.create({
    channel: "OrganizationChannel",
    organization_id: organizationID
  },{
    connected() {
      console.log('connected')
    },
    received(data) {
      alert("hey")
      const budgetSpentCents = parseInt(data['budget_spent_cents'])
      const budgetSpentUnit = budgetSpentCents / 100.0
      const trainingBudgetTotal = document.getElementById('training-budget-total')
      const currentTrainingBudgetTotal = parseInt(trainingBudgetTotal.textContent)
      trainingBudgetTotal.textContent = currentTrainingBudgetTotal + budgetSpentUnit
    }

This works well, and I can see the ruby channel code being executed :

class OrganizationChannel < ApplicationCable::Channel
  def subscribed
    binding.pry
    organization = Organization.find(params[:organization_id])
    stream_from organization
  end

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

However I am stuck when I try to broadcast to that particular client (organization). Here 's my attempt :

  OrganizationChannel.broadcast_to(
          Organization.first,
          budget_spent_cents: Registration.last&.training_budget_transaction&.total_cents
        )

which returns 0 and

[ActionCable] Broadcasting to organization:Z2lkOi8veXVub28vT3JnYW5pemF0aW9uLzE: {:budget_spent_cents=>-5000}

the received(data) hook in my client code is never executed... Im not sure why ? My guess is because Z2lkOi8veXVub28vT3JnYW5pemF0aW9uLzE is not the actual id of the organization (what is that string actually ?) and it doesnt find the proper channel to broadcast to.

How would you setup the broadcasting right in that situation ?


Solution

  • Z2lkOi8veXVub28vT3JnYW5pemF0aW9uLzE is the global id for the organization you are testing with. organization:Z2lkOi8veXVub28vT3JnYW5pemF0aW9uLzE is the channel name generated and used by the OrganizationChannel.broadcast_to method based on the arguments you are passing.

    On your OrganizationChannel class, instead of using stream_from organization use stream_for organization. That will tell the client to properly stream from the organization:#{global_id} channel.