Frame layout
The Slic transport protocol sends data over a duplex connection in protocol frames. The reading and writing of these frames are serialized on the underlying duplex connection.
Frames and types from this page are defined using Slice.
All the frames have a header and a body. The header layout is common to all Slic versions and is composed of the following fields:
- a frame type defined as an
uint8enumeration - a frame size defined as a
varuint62representing the size of the frame body.
The frame type is defined as follows:
enum FrameType : uint8 { Initialize = 1 InitializeAck Version Close Ping Pong Stream StreamLast StreamReadsClosed StreamWindowUpdate StreamWritesClosed}All Slic versions support the Initialize and Version frames. All the other frames are version-specific.
Initialize frame
An Initialize frame carries parameters sent by a client to a server on connection establishment. It's defined as follows:
compact struct InitializeFrame { frameType: FrameType // = FrameType::Initialize frameSize: varuint62 version: varuint62 // = 1 (Slic version 1) parameters: ParameterFields}
unchecked enum ParameterKey : varuint62 { MaxBidirectionalStreams = 0 MaxUnidirectionalStreams = 1 IdleTimeout = 2 InitialStreamWindowSize = 3 MaxStreamFrameSize = 4}
typealias ParameterFields = Dictionary<ParameterKey, Sequence<uint8>>The parameters are used to configure the connection.
All Slic versions support an Initialize frame with a body that starts with a version field. The remainder of the body is version-specific. If the server doesn't support the version from the Initialize frame, it must respond with a Version frame that specifies the versions it supports.
InitializeAck frame
An InitializeAck frame carries parameters. It's defined as follows:
compact struct InitializeAckFrame { frameType: FrameType // = FrameType::InitializeAck frameSize: varuint62 parameters: ParameterFields}The parameters are used to configure the connection.
Version frame
A Version frame carries a sequence of varint62 values where each value specifies a Slic version. It is sent by a server on connection establishment if the Slic version specified in the Initialize frame is not supported. It's defined as follows:
compact struct VersionFrame { frameType: FrameType // = FrameType::Version frameSize: varuint62 versions: Sequence<varuint62>}All Slic versions support this frame.
Close frame
A Close frame carries an application error code. It's defined as follows:
compact struct CloseFrame { frameType: FrameType // = FrameType::Close frameSize: varuint62 applicationErrorCode: varuint62}The application error code is provided by the application on connection closure.
Ping frame
A Ping frame carries an opaque payload. It's defined as follows:
compact struct PingFrame { frameType: FrameType // = FrameType::Ping frameSize: varuint62 payload: OpaqueData}
custom OpaqueData // 64-bits opaque dataA Pong frame with the same opaque payload must be sent after receiving a Ping frame.
The Ping frame can be used for different purposes. For example, it can be used to prevent a connection from becoming idle or to measure the round-trip time (RTT). The opaque payload allows to identify the different Ping frames.
Pong frame
An Pong frame carries an opaque payload. It's defined as follows:
compact struct PongFrame { frameType: FrameType // = FrameType::Pong frameSize: varuint62 payload: OpaqueData}A Pong frame is sent in response of a Ping frame. It must include the same payload as the Ping frame.
Stream and StreamLast frames
A Stream or StreamLast frame carries the application payload. It consists of the frame header followed by the stream ID and application data. It's defined as follows:
compact struct StreamFrame { frameType: FrameType // = FrameType::Stream or FrameType::StreamLast frameSize: varuint62 streamId: varuint62 // Application payload bytes}StreamReadsClosed and StreamWritesClosed frames
A StreamReadsClosed or StreamWritesClosed frame doesn't carry any data. Both frames are defined as follows:
compact struct StreamClosedFrame { frameType: FrameType // = FrameType::StreamWritesClosed or FrameType::StreamReadsClosed frameSize: varuint62 streamId: varuint62}These frames are sent when reads or writes are closed on the stream.
StreamWindowUpdate frame
A StreamWindowUpdate frame carries a window size increment value. It's defined as follows:
compact struct StreamWindowUpdateFrame { frameType: FrameType // = FrameType::StreamWindowUpdate frameSize: varuint62 streamId: varuint62 windowSizeIncrement: varuint62}The window size increment specifies the additional number of bytes that can be sent in addition to the existing window size.