-
Notifications
You must be signed in to change notification settings - Fork 50
Docs: Wire protocol
To efficiently exchange messages over a TCP connection, DRPC uses frames to exchange bits of information. Frames are created from packets which contain a single message sent by drpc. Packets may be split into multiple frames depending on the size of the message that is trying to be sent.
Frames in DRPC have the following layout.
- Header (1 byte)
- Stream ID (1 - 10 bytes, 64-bit varint)
- Message ID (1 - 10 bytes, 64-bit varint)
- Length (1-10 bytes, 64-bit varint)
- Data (Length bytes)
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Header | Stream ID | Message ID | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Data... |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Header byte is composed of three pieces of information.
- A single bit indicating if this is a control frame. (
(h & 0b10000000) > 0
) - Six bits identifying the kind of message the frame contains. (
(h & 0b01111110) >> 1
) - A single bit indicating if this is the last frame of a packet. (
(h & 0b00000001) > 0
)
0b0_000000_0
│ │ │ └─ Done (1 bit)
│ └────┴─── Kind (6 bits)
└────────── Control (1 bit)
The Stream ID, Message ID and Length fields are variable width encoded integers using the same format as protobuf. See the protobuf documentation for a discussion on how they are encoded.
DRPC allocates enough space for 64 possible message types. There are 6 in use today.
Value | Name | Meaning |
---|---|---|
1 | Invoke | Invoke is used to invoke an RPC. The body is the name of the RPC. |
2 | Message | Message is used to send messages. The body is an encoded message. |
3 | Error | Error is used to inform that an error happened. The body is an error with a code attached. |
4 | --- | --- |
5 | Close | Close is used to inform that the RPC is dead. It has no body. |
6 | CloseSend | CloseSend is used to inform that no more messages will be sent. It has no body. |
7 | InvokeMetadata | Invoke metadata includes metadata about the next Invoke packet with the same stream ID. |
Since a single packet in DRPC can be split into multiple frames, packets need to be reassembled given their individual chunks. To assemble a packet from its distinct frames:
- Check the control bit. If it’s set, then skip the frame (TBD)
- Check the incoming frame (a frame ID is the combination of Stream ID and Message ID)
- If the incoming frame ID is less than the last processed frame ID, then the system should error. Frame IDs sent along a connection should be monotonically increasing.
- If the incoming frame ID is greater than the last processed frame ID, then a new Packet is started from the frame and the last processed frame ID is updated to the incoming frame ID.
- If the frame ID is the same, but the kind of frame differs from the current packet then the system should error. Packet kinds should not change between their frames.
- If the frame ID and kind are the same, then the data is appended to the current packet.
- Check the done bit. If it’s set, then the packet is complete.
- If not, read the next frame and repeat the process until the done bit is set or an error occurs.