MessagePack Protocol
The MessagePack protocol is more compact than JSON and is recommended for
high-volume binary traffic. Each message is a MessagePack array prefixed by
a VarInt length (see the binary framing helpers in
aiosignalr.framing.binary).
Selection
connection = HubConnection(protocol="messagepack")
MessagePack requires a Binary-capable transport (WebSocket or Long Polling — not Server-Sent Events).
Message arrays
The first array element is the message type:
type | Message | Array shape |
|---|---|---|
| 1 | Invocation | [1, headers, invocationId?, target, args[], streamIds[]] |
| 2 | StreamItem | [2, headers, invocationId, item] |
| 3 | Completion | [3, headers, invocationId, resultKind, result?] |
| 4 | StreamInvocation | [4, headers, invocationId, target, args[], streamIds[]] |
| 5 | CancelInvocation | [5, headers, invocationId] |
| 6 | Ping | [6] |
| 7 | Close | [7, error?, allowReconnect] |
| 8 | Ack | [8, sequenceId] |
| 9 | Sequence | [9, sequenceId] |
Completion result kinds
| Value | Meaning |
|---|---|
| 1 | Error ([3, headers, invocationId, 1, errorMessage]) |
| 2 | Void (no result) |
| 3 | Non-void result ([3, headers, invocationId, 3, result]) |
Framing
Every message is prefixed with its byte length as a VarInt:
from aiosignalr.framing import encode_binary_message
frame = encode_binary_message(msgpack.packb([6])) # Ping
On the wire over WebSocket this goes out as a binary frame; the parser assembles complete frames incrementally.
Example
Invocation (Add with invocationId "1"):
[1, {}, "1", "Add", [40, 2], []]
StreamItem:
[2, {}, "1", 0]
Ack:
[8, 7]
Parser behavior
- Unknown message types are ignored.
- The first element must be a message type; invalid payloads raise a
ProtocolError. - The MessagePack array is unpacked with
raw=False, so string keys come back as Pythonstr.
Performance notes
MessagePack avoids the JSON text overhead entirely. Use it when:
- Message volume is high (telemetry, games, financial tick streams).
- Payloads contain binary-safe values.
- Bandwidth is constrained.