Action Cable Overview — Ruby on Rails Guides
Full code:
Server will call receive if client send. Below line just sends from Server to all clients.
class GuruChannel < ApplicationCable::Channel
STREAM_PREFIX = 'GuruChannel'
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
def subscribed
stream_from(stream)
transmit(stream_state)
end
def receive(data)
message = to_json(data).fetch(:message)
ActionCable.server.broadcast(stream, message)
end
private
def stream
"#{STREAM_PREFIX}_#{job_slug}"
end
def job_slug
params.fetch(:job_slug)
end
def to_json(data)
JSON.parse(data.to_json, symbolize_names:true)
end
def stream_state
Redis.current.get(stream)
end
end
Using transmit to send message to only the current connection.def subscribed
stream_from(stream)
transmit(stream_state)
end
Using broadcast to broadcast message to all connections. Message won't be sent directly from client to client, but from client to server. Server broadcast message to clients then.
def receive(data)
message = to_json(data).fetch(:message)
ActionCable.server.broadcast(stream, message)
end
Server will call receive if client send. Below line just sends from Server to all clients.
ActionCable.server.broadcast(stream, message)
Note that we must configure redis same as the server using Socket /cable if using multiple servers.
development:
adapter: redis
url: redis://localhost:6379
test:
adapter: async
staging:
adapter: redis
url: redis://willnguyen.com:6379
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
For example. We have the second one for background job. If we use ActionCable in background job, we have to point to the Redis that the first server uses - The same Redis to let two servers see the same number of connections.
server 'xxx.xxx.xxx.xx', user: 'truong', roles: %w{app db web}, primary: true
server 'yy.yyy.yyy.yyy', user: 'truong', roles: %w{app worker whenever}