hat.drivers.chatter - Chatter communication protocol¶
Hat defines a communication infrastructure used by Hat back-end components. This communication is based on the TCP communication protocol (with the option of applying an SSL layer on top of TCP) and messages encoded using SBS. The underlying stream is segmented into blocks. Each block contains a single communication message prefixed by its message header. This header consists of 1+m bytes where the first byte contains the value m (from 0 to 255, or header byte length), while the m bytes value determines the number of following message bytes (k) encoded as big-endian (the first byte value does not include the first header byte and message length does not include header length) which contain the actual body of the message.
Visualization of the communication stream:
address ... | n | n+1 | ... | n+m | n+m+1 | ... | n+m+k | ...
-------+-----+-----+-------+-----+-------+-------+-------+-------
data ... | m | k | message | ...
-------+-----+-----+-------+-----+-------+-------+-------+-------
where:
m is byte length of k
k is byte length of message (n+1 is the most significant byte)
message is SBS encoded message data.
All Communication is peer-to-peer based. One peer connects to another and once the connection is achieved, each peer can send messages to the other peer in full duplex fashion. Each peer can terminate the connection if necessary. Most communication errors (including data serialization errors) will result in connection termination.
Message¶
Communication message is defined by SBS HatChatter.Msg containing:
unique message identifier (id)
conversation descriptor (first, owner, token, last)
message data (data) determined by type identifier (‘type’)
Message identifier is a number which uniquely identifies a peer’s message. When a new connection is established, each peer bounds a counter to the connection. Upon sending a new message, this counter is incremented and used as the new message’s identifier.
Conversation descriptor consists of a set of parameters which bind the message to a specific conversation (see Conversation).
Message data consists of bytes with additional type identifier. Usually type
represents SBS type identifier and data contains SBS encoded data
(this kind of data encoding is not mandated by Chatter). Type identifiers
starting with HatChatter.
are reserved for Chatter internal encoding and
should not be used.
SBS message schema:
module HatChatter
Msg = Record {
id: Integer
first: Integer
owner: Boolean
token: Boolean
last: Boolean
data: Data
}
Data = Record {
type: String
data: Bytes
}
Ping = None
Pong = None
Conversation¶
A Conversation is defined as an ordered finite sequence of messages. Conversations are used for short ordered exchange of messages between two peers. Each peer can start a new conversation and finalize an existing conversation. Multiple simultaneously active conversations can be bound to a single active connection. A basic example for conversation usage is a request-response message exchange between peers.
Each message contains its conversation descriptor which contains:
conversation’s first message identifier (first)
owner flag (owner)
token passing flag (token)
last message flag (last)
A Conversation’s first message identifier contains the message identifier of the message which started the conversation. If this identifier is equal to the current message’s identifier, the message is the first message in the conversation.
The peer who initiates a conversation (sends the first message in the
conversation) is considered to be the conversation’s owner. A message’s
owner flag (owner) is set to true
only if the peer sending the message is
also the conversation’s owner.
The token passing flag (token) is set to true
if this message is the last
message this peer will send prior to expecting messages (bound to the current
conversation) from the other peer. This behavior is an implementation of the
token passing mechanism. Initially, the token is given to the peer who
initiates the conversation. This peer can pass the token to the other peer by
setting the token passing flag (token) to true
. Only the peer currently
holding the token can send messages bound the conversation.
The last message flag (last) is set to true
only if the message is the
last message in the current conversation. Once this message is sent, the
conversation can not be used to send new messages. When the last flag (last)
is set to true
, the value of the token passing flag is ignored.
Each conversation is uniquely identified by its first message identifier and owner flag.
Ping¶
In addition to exchanging user data, Chatter defines Ping message exchange. This is a peer-to-peer service (there is no distinction between client and server).
A Ping - Pong Conversation between peers contains these messages:
Message
Conversation
Direction
First
Last
Ping
T
F
p1 > p2
Pong
F
T
p2 > p1
where ‘p1’ and ‘p2’ are two communicating peers.
Each peer can send Ping message at any time. Once Ping message is received, peer receiving this message should immediately sent paired Pong message and close the conversation.
The Ping communication is usually used as basis for closed connection detection. It is recommended that each peer sends new Ping request only after configurable time period has passed from receiving last message. Usually, any kind of message should restart ping delay/timeout (not only Pong message).
API¶
API reference is available as part of generated documentation: