Action Cable Protocol
Action Cable is a framework that allows you to integrate WebSockets with the rest of your Rails application easily.
It uses a simple JSON-based protocol for client-server communication.
Messages
Communication is based on messages. Every message is an object.
Protocol-related messages from server to client MUST have type
field (string).
Possible types:
- [
welcome
] - [
disconnect
] - [
ping
] - [
confirm_subscription
] - [
reject_subscription
]
There are also data messages–broadcasts and transmissions–they MUST have message
field.
Protocol-related messages from client to server MUST have command
field (string).
Possible commands:
- [
subscribe
] - [
unsubscribe
] - [
message
]
Handshake
When client connects to server one of the following two could happen:
- server accepts the connection and responds with
welcome
message ({"type":"welcome"}
) - server rejects the connection and responds with a
disconnect
message, which may include fieldsreason
andreconnect
({"type":"disconnect", "reason":"unauthorized", "reconnect":false}
)*
Server MUST respond with either a welcome
message or a disconnect
message.
* disconnect
message only exists in Rails 6.0 and later. Prior to 6.0, server would drop the connection without sending anything.
Subscriptions & identifiers
Data messages, client-to-server messages and some server-to-client messages (confirm_subscription
, reject_subscription
) MUST contain identifier
field (string) which is used to route data to the specified channel.
It's up to server and client how to generate and resolve identifiers.
Rails identifiers schema is the following: { channel: "MyChannelClass", **params }.to_json
.
For example, to subscribe to ChatChannel
with id: 42
client should send the following message:
{
"identifier": "{\"channel\":\"ChatChannel\",\"id\":42}",
"command": "subscribe"
}
The response from server MUST contain the same identifier, e.g.:
{
"identifier": "{\"channel\":\"ChatChannel\",\"id\":42}",
"type": "confirm_subscription"
}
To unsubscribe from the channel client should send the following message:
{
"identifier": "{\"channel\":\"ChatChannel\",\"id\":42}",
"command": "unsubscribe"
}
There is no unsubscription confirmation sent (see PR#24900).
Receive messages
Data message from server to client MUST contain identifier
field and message
field with the data itself.
Perform actions
Action message from client to server MUST contain command
("message"), identifier
fields, and data
field containing a JSON-encoded value.
The data
field MAY contain action
field.
For example, in Rails to invoke a method on a channel class, you should send:
{
"identifier": "{\"channel\":\"ChatChannel\",\"id\":42}",
"command": "message",
"data": "{\"action\":\"speak\",\"text\":\"hello!\"}"
}
Ping
Although WebSocket protocol describes low-level ping
/pong
frames to detect dropped connections, some implementation (e.g. browsers) don't provide an API for using them.
That's why Action Cable protocol has its own, protocol-level pings support.
Server sends ping
messages ({ "type": "ping", "message": <Time.now.to_i>}
) every X seconds (3 seconds in Rails).
Client MAY track this messages and decide to re-connect if no ping
messages have been observed in the last Y seconds.
For example, default Action Cable client reconnects if no ping
messages have been received in 6 seconds.