Skip to content

Instantly share code, notes, and snippets.

@fcarriedo
Created August 23, 2012 21:46
Show Gist options
  • Save fcarriedo/3442300 to your computer and use it in GitHub Desktop.
Save fcarriedo/3442300 to your computer and use it in GitHub Desktop.
Technovision/ZoomSystems comms spec.

NCube's and ZoomShop communication specification

In a 20 thousand feet view, two persistent communication channels* will be maintained, one for commands generally coming from the ZoomShop (client) to the NCube (server) for dispensing, inventory requests, etc. in an RPC style and another one for events (in fire-and-forget style) which flow is to be started from the NCube (server) to the ZoomShop (client).

Having persistent connections benefits both parties as both can immediately detect when a connection was broken and take the appropriate measures.

On a related note, but not relevant to this document, both commands and events messages (see NCube Protocol Format > Messages) are to be serialized as XML documents.

*Note: Within this document, the term stream, socket connection and channel are treated as synonyms.

Session

A session is said to be initiated or established when both parties (client and server) have negotiated their commands and events channels (see Handshake), have persistent connections to them and are ready for letting commands and events flow back and forward through the associated streams.

In case a client starts sending commands without the session properly initialized, a corresponding protocol error should be returned (see NCube Protocol Format > Errors).

In case the client gets disconnected, the session has to be reset to uninitialized until a new session is correctly established. The server has to be resilient to client disconnections/re-connections.

The Handshake

The handshake is comprised of two subsequent sockets connections with the corresponding Protocol Control initialization command (in no particular order) - (see NCube Protocol Format > Protocol Control commands). For each of them, the server should return a success Protocol Control response if there were no errors.

The session is said to be initiated only when the two streams ('commands' and 'events') were established and no error was returned in the process.

Once the handshake has taken place and thus the session considered to be initiated, the handshake is considered to be complete and both commands and events can start to flow freely on both directions.

Due to the nature of our application (robot control in some cases), the server can only service one and only one client. In case a new handshake tries to take place under a correctly initialized ongoing session, the server should ignore it (idempotent) and should notify the client the connection is being ignored before closing it (see NCube Protocol Format > Protocol Commands).

The server should immediately become receptive to a new handshake if any of the connections broke and thus session became unstable.

The Plumbing

At a low level, the communication between client and server happens in packets of NCube Protocol Formats (NCProto).

NCube Protocol Format (NCProto)

The overall format of an NCProto is:

+-------+----+-------------+
|1      |1   |N            |
|-------|----|-------------|
|Version|Type|Data         |
+-------+----+-------------+

Where:

  • Version (1 byte): representing the version of the protocol (currently 1)
  • Type (1 byte): representing the type.
    • Possible values:
      • 1 for Protocol Control
      • 2 for Messages
      • 3 for Error
  • Data (N bytes): Whatever data is represented on the NCProto. If Type specifies a message, then its the message bytes, if the Type is an error, then a 1 byte Err Type follows with an Err Desc immediately after (see Errors), etc.

Protocol Control commands

When the Type is specified as Protocol Control (1) the Data is just one byte:

+-------+----+-------------+
|1      |1   |1            |
|-------|----|-------------|
|Version|Type|Data         |
+-------+----+-------------+

The 1 byte Data can have any of the following values:

  • 0: success - Generally an 'ok' response from the server to any protocol control commands. If there is an error, like unsupported version, an error type should be returned with the according description (see Errors)
  • 1: connection request ignored - Returned by the server if there is already an ongoing correctly initialized session.
  • 10: initialize commands stream - Generally used at handshake (see handshake)
  • 20: initialize events stream - Generally used at handshake (see handshake)

Messages

Once the handshake has been done (session established) this types will most likely constitute the bulk of the communication.

The format is as follows

+-------+----+-------------+
|1      |1   |N            |
|-------|----|-------------|
|Version|Type|Message Data |
+-------+----+-------------+

where Type will be 2 and Data is just a set of UTF-8 encoded bytes that can be reconstructed into a string.

Errors

When there is a protocol error, e.g.: the version specified on a request is not supported, or a client is trying to send a message and the session hasn't been initiated (no handshake), or an unsupported type was set, there should be an error returned.

The format of the error follows:

+-------+----+--------+-------------+
|1      |1   |1       |N            |
|-------|----|--------|-------------|
|Version|Type|Err Type|Err Desc     |
+-------+----+--------+-------------+

Where Err Type can have any of the following values:

  • 30: Uninitialized Session
  • 40: Unsupported Version
  • 41: Unrecognized Type
  • 42: Malformed NCProto - When the NCProto doesn't conform to the spec.
  • 50: Server Error

The Err Desc is optional though encouraged. It should be a UTF-8 encoded string with the description/stack-trace of the error.

Packets

To transmit the NCProtos over the wire we use the concept of packets. A packet is an NCProto simply prepended with a four byte integer (big endian) as header representing its length.

For example, a 20 byte NCProto, would have the binary header:

00000000 00000000 00000000 00010100

The header would be followed by 20 bytes of NCProto data, making the packet 24 bytes overall. Reading streams of NCProtos involves reading the four byte header, then reading as many bytes as specified in the length, and starting over again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment