17 KiB
Azure SignalR Service Protocol
The Azure SignalR Service Protocol is a protocol between Azure SignalR Service and user application (server side) to provide an abstract transport between application clients and application server.
Terms
- Service - Azure SignalR Service. It accepts connections from both clients and servers, acting as the abstract transport between them. It will internally maintain a one-to-one mapping between clients and servers, to make sure that messages are correctly routed to the recipients as if it is a physical transport.
- Server - Application server node, which is connected to the Azure SignalR Service, using this protocol to receive data from and send data to clients through Azure SignalR Service.
- Client - The SignalR client connected to the Azure SignalR Service. The Azure SignalR Service will look exactly the same as a self-hosted SignalR server from the client's perspective.
Overview
Azure SignalR Service Protocol uses WebSockets and MessagePack to proxy messages between Service and Server. Messages are categorized into three groups:
Service Connection Message
These messages are used to establish and maintain the physical connection between Service and Server.
Message Name | Sender | Description |
---|---|---|
HandshakeRequest | Server | Sent by Server to negotiate the protocol version before the physical connection is established. |
HandshakeResponse | Service | Sent by Service to tell Server whether the requested protocol version is supported. If yes, connection will be successfully established. Otherwise, connection will be closed. |
Ping | Service or Server | Sent by either side to check the connection is alive. |
Generic Client Connection Message
Multiple logical client connections will be multiplexed in one or a few (far less than the number of client connections) physical connections between Service and Server. These messages are used to operate a single logical client connection within a physical connection.
Message Name | Sender | Description |
---|---|---|
OpenConnection | Service | Sent by Service to notify Server there is a new client connected. |
CloseConnection | Service or Server | Sent by either side to notify the other side that the specified connection should be closed. |
ConnectionData | Service or Server | When sent from Service to Server, it contains data from a single client. When sent from Server to Service, it contains data which should be delivered to a single client. |
SignalR-specific Message
These messages map to the various operations in the SignalR framework.
Message Name | Sender | Description |
---|---|---|
MultiConnectionData | Server | Sent from Server to Service. Payloads in the message will be sent to multiple connections by Service. |
UserData | Server | Sent from Server to Service. Payloads in the message will be sent to the target user (possible multiple connections) by Service. |
MultiUserData | Server | Sent from Server to Service. Payloads in the message will be sent to multiple connections by Service. |
BroadcastData | Server | Sent from Server to Service. Payloads in the message will be broadcasted to all connected clients by Service. |
JoinGroup | Server | Sent by server to ask Service adding the target connection to the target group. |
LeaveGroup | Server | Sent by server to ask Service removing the target connection from the target group. |
GroupBroadcastData | Server | Sent from Server to Service. Payloads in the message will be broadcasted to all connections within the target group by Service. |
MultiGroupBroadcastData | Server | Sent from Server to Service. Payloads in the message will be broadcasted to all connections within the target groups by Service. |
JoinGroupWithAck | Server | Sent by server to ask Service adding the target connection to the target group. Server will wait for the ack to continue. |
LeaveGroupWithAck | Server | Sent by server to ask Service removing the target connection from the target group. Server will wait for the ack to continue. |
Ack | Service | Sent from Service to Server to return the operation result of JoinGroupWithAck and LeaveGroupWithAck |
ClientInvocationMessage | Server | Sent from Server to Service. Payloads in the message will be sent to client for client invocation. Sent from Server to Server. When global routed, it's a register message to router server to handle client invocation results. |
ClientCompletionMessage | Server | Sent from Server to Service with success client invocation results to let service do clean-up. Sent from Server to Server when global routed. |
ErrorCompletionMessage | Server/Service | Sent from Service to Server with error like client drops or timeout in client invocation. Sent from Server to Server when global routed. |
ServiceMappingMessage | Service | Sent from Service to aware client invocation mapped instance. |
Communication Model
This protocol will be used between Service and Server. There will be one or a few physical connections between Service and Server. Data from/to multiple client connections will be multiplexed within these physical connections. Each client connection will be identified by a unique connection Id.
The number of client connections will be far more (over 100 times) than the number of physical connections between Service and Server.
Handshake
Server will initiate a physical connection to Service, using WebSocket transport. Once the WebSocket connection is established, Server will send a HandshakeRequest
message with a requested version number of Azure SignalR Service Protocol to service.
- If the protocol version is supported, Service will send a success
HandshakeResponse
message to Server. Then the communication begins. - Otherwise, Service will send a
HandshakeResponse
message with error, and the physical connection will be closed.
New Client Connect
When a new client is connected to Service, a OpenConnection
message will be sent by Service to Server.
Client migrate-in from another server
When a new client is migrated from another server, a OpenConnection
message will be sent by Service to Server, with an Asrs-Migrated-From
header given.
Client Disconnect
- When a client is disconnected from Service, a
CloseConnection
message will be sent by Service to Server. - When Server wants to disconnect a client, a
CloseConnection
message will be sent by Server to Service. Then Service will disconnect the phyical connection with the target client.
Client migrate-out to another server
When a client is migrated to another server, a CloseConnection
message will be sent by Service to Server, with an Asrs-Migrated-To
header given.
Client Data Pass Through
- When a client sends data to Service, a
ConnectionData
message will be sent by Service to Server. - When Server wants to send data to a client, a
ConnectionData
message will be sent by Server to Service.
SignalR scenarios
Service supports various scenarios in SignalR to send data from Server to multiple clients.
- When Server wants to send data to a specific set of connections, a
MultiConnectionData
message is sent to Service, containing the list of the target connections. - When Server wants to send data to a specific user, a
UserData
message is sent to Service. - When Server wants to send data to a specific set of users, a
MultiUserData
message is sent to Service, containing the list of the target users. - When Server wants to send data to all clients, a
BroadcastData
message is sent to Service. - When Server wants to send data to a specific group, a
GroupBroadcastData
message is sent to Service. - When Server wants to send data to a couple of groups, a
MultiGroupBroadcastData
message is sent to Service.
SignalR service pings
Service enable pings for various scenarios of feature support and status sync between server and service.
Key | Value | Direction | Description |
---|---|---|---|
EMPTY | EMPTY | Both | Keep server connection alive ping |
target |
<instanceId> |
Service -> Server | Rebalance ping to request server connection to improve availability |
status |
EMPTY | Server -> Service | Request to know whether service has clients |
status |
0 or 1 |
Service -> Server | Response to status ping of whether service has clients |
offline |
fin:0 |
Server -> Service | Request to drop clients for non-migratable server connections |
offline |
fin:1 |
Server -> Service | Request to migrate client connections |
offline |
finack |
Service -> Server | Response of received offline request |
servers |
EMPTY | Server -> Service | Request to get all server ids connect to the service |
servers |
<timestamp>:<server1>;<server2> |
Service -> Server | Response of servers ping of all server ids |
echo |
<identify> |
Service <-> Server | Identify the latency of server connection, available from SDK 1.21.6. |
Message Encodings
In Azure SignalR Service Protocol, each message is represented as a single MessagePack array containing items that correspond to properties of the given service message.
MessagePack uses different formats to encode values. Refer to the MessagePack Format Spec for format definitions.
HandshakeRequest Message
HandshakeRequest
messages have the following structure.
[1, Version]
- 1 - Message Type, indicating this is a
HandshakeRequest
message. - Version - A
Int32
encoding number of the protocol version. - ConnectionType - A
Int32
encoding number of the connection type.- 0, Default, it can carry clients, service runtime should always accept this kind of connection.
- 1, OnDemand, creating when service requested more connections, it can carry clients, but it may be rejected by service runtime.
- 2, Weak, it can not carry clients, but it can send message.
- MigrationLevel - A
Int32
encoding number indicates if further client connections associated with this server connection could be migrated.- 0, Off, a client connection can not be migrated to another server.
- 1, ShutdownOnly, a client connection can be migrated only if the matched server was shutdown gracefully.
- 2, Any, a client connection can be migrated even if the matched server connection was dropped accidentally. (may cause data loss)
Example: TODO
HandshakeResponse Message
HandshakeResponse
messages have the following structure.
[2, ErrorMessage]
- 2 - Message Type, indicating this is a
HandshakeResponse
message. - ErrorMessage - A
String
encoding error message. Null means handshake success, otherwise it means there is error.
Example: TODO
Ping Message
Ping
messages have the following structure.
[3, Messages]
- 3 - Message Type, indicating this is a
Ping
message. - Messages - An
Array
ofString
indicatesPing
message type and value.
Example: TODO
OpenConnection Message
OpenConnection
messages have the following structure.
[4, ConnectionId, Claims]
- 4 - Message Type, indicating this is a
OpenConnection
message. - ConnectionId - A
String
encoding unique Id for the connection. - Claims - A MessagePack Map containing all claims of this client.
Example: TODO
CloseConnection Message
CloseConnection
messages have the following structure.
[5, ConnectionId, ErrorMessage]
- 5 - Message Type, indicating this is a
CloseConnection
message. - ConnectionId - A
String
encoding unique Id of the connection. - ErrorMessage - Optional
String
encoding error message.
Example: TODO
ConnectionData Message
ConnectionData
messages have the following structure.
[6, ConnectionId, Payload]
- 6 - Message Type, indicating this is a
ConnectionData
message. - ConnectionId - A
String
encoding unique Id for the connection. - Payload -
Binary
encoding of the raw bytes from/to the connection.
Example: TODO
MultiConnectionData Message
MultiConnectionData
messages have the following structure.
[7, ConnectionList, Payloads]
- 7 - Message Type, indicating this is a
MultiConnectionData
message. - ConnectionList - An array containing
String
encoding Ids of the target connections. - Payloads - A MessagePack Map containing payloads, with string keys and byte array values. The key is the protocol name of the value.
Example: TODO
UserData Message
UserData
messages have the following structure.
[8, UserId, Payloads]
- 8 - Message Type, indicating this is a
UserData
message. - UserId - A
String
encoding unique Id for the user. - Payloads - A MessagePack Map containing payloads, with string keys and byte array values. The key is the protocol name of the value.
Example: TODO
MultiUserData Message
MultiUserData
messages have the following structure.
[9, UserList, Payloads]
- 9 - Message Type, indicating this is a
MultiUserData
message. - UserList - An array containing
String
encoding Ids of the target users. - Payloads - A MessagePack Map containing payloads, with string keys and byte array values. The key is the protocol name of the value.
Example: TODO
BroadcastData Message
BroadcastData
messages have the following structure.
[10, ExcludedList, Payloads]
- 10 - Message Type, indicating this is a
BroadcastData
message. - ExcludedList - An array containing
String
encoding Ids of the connections, which will not receive payload in this message. - Payloads - A MessagePack Map containing payloads, with string keys and byte array values. The key is the protocol name of the value.
Example: TODO
JoinGroup Message
JoinGroup
messages have the following structure.
[11, ConnectionId, GroupName]
- 11 - Message Type, indicating this is a
JoinGroup
message. - ConnectionId - A
String
encoding unique Id for the connection. - GroupName - A
String
encoding group name, which the connection will join.
Example: TODO
LeaveGroup Message
LeaveGroup
messages have the following structure.
[12, ConnectionId, GroupName]
- 12 - Message Type, indicating this is a
LeaveGroup
message. - ConnectionId - A
String
encoding unique Id for the connection. - GroupName - A
String
encoding group name, which the connection will leave.
Example: TODO
GroupBroadcastData Message
GroupBroadcastData
messages have the following structure.
[13, GroupName, ExcludedList, Payloads]
- 13 - Message Type, indicating this is a
GroupBroadcastData
message. - GroupName - A
String
encoding target group name. - ExcludedList - An array containing
String
encoding Ids of the connections, which will not receive payload in this message. - Payloads - A MessagePack Map containing payloads, with string keys and byte array values. The key is the protocol name of the value.
Example: TODO
MultiGroupBroadcastData Message
MultiGroupBroadcastData
messages have the following structure.
[14, GroupList, Payloads]
- 14 - Message Type, indicating this is a
MultiGroupBroadcastData
message. - GroupList - An array containing
String
encoding target group names. - Payloads - A MessagePack Map containing payloads, with string keys and byte array values. The key is the protocol name of the value.
Example: TODO
UserJoinGroup Message
UserJoinGroup
messages have the following structure.
[16, UserId, GroupName]
- 16 - Message Type, indicating this is a
UserJoinGroup
message. - UserId - A
String
encoding unique Id for the user. - GroupName - A
String
encoding group name, which the user will join.
Example: TODO
UserLeaveGroup Message
UserLeaveGroup
messages have the following structure.
[17, UserId, GroupName]
- 17 - Message Type, indicating this is a
UserLeaveGroup
message. - UserId - A
String
encoding unique Id for the user. - GroupName - A
String
encoding group name, which the user will leave.
Example: TODO
JoinGroupWithAck Message
JoinGroupWithAck
messages have the following structure.
[18, ConnectionId, GroupName, AckId]
- 18 - Message Type, indicating this is a
JoinGroupWithAck
message. - ConnectionId - A
String
encoding unique Id for the connection. - GroupName - A
String
encoding group name, which the connection will join. - AckId - A
Int32
encoding Id number to identify the corresponding ack message.
Example: TODO
LeaveGroupWithAck Message
LeaveGroupWithAck
messages have the following structure.
[19, ConnectionId, GroupName, AckId]
- 19 - Message Type, indicating this is a
LeaveGroupWithAck
message. - ConnectionId - A
String
encoding unique Id for the connection. - GroupName - A
String
encoding group name, which the connection will leave. - AckId - A
Int32
encoding Id number to identify the corresponding ack message.
Example: TODO
Ack Message
Ack
messages have the following structure.
[20, AckId, Status, Message]
- 20 - Message Type, indicating this is a
Ack
message. - AckId - A
Int32
encoding Id number to associate the corresponding message. - Status - A
Int32
encoding status code to indicate the operation result. - Message - A
String
encoding ack message to explain status details.