Skip to content

Wire Protocol

Ben Olden-Cooligan edited this page Mar 8, 2023 · 7 revisions
  1. Communication.
  • Communication is performed using packets.
  • The contents of a named pipe message are a single packet.
  • A packet may contain any number of TransportMessage protos or raw binary payloads in sequence with no delimiting.
  1. Data representation.
  • This wire protocol uses protobufs for protocol messages.
  • The TransportMessage proto is defined here and includes several types of messages in a oneof:
    • RequestInit, Headers, PayloadInfo, RequestControl, Trailers
  1. Initialization.
  • Once the pipe connection is initiated, the client sends a RequestInit message with the fully qualified name of the method to call, and optionally a deadline.
  • The client then sends a Headers message with any gRPC request headers.
  • Pipe connections currently cannot be reused for multiple calls, a new pipe connection must be made for each. (This may be changed in the future.)
  1. Client requests.
  • For unary and server-streaming methods, the client sends a PayloadInfo message and the request payload immediately after sending the headers.
  • For client-streaming and duplex methods, the client can send any number of request payloads at any time. This should be followed by a RequestControl message with a value of stream_end once there are no more request payloads to be sent.
  1. Server responses.
  • For unary and client-streaming methods, the server sends a PayloadInfo message, the response payload, and a Trailers message after processing is complete (and in the case of client-streaming after receiving stream_end).
  • For server-streaming and duplex methods, the server can send any number of request payloads at any time. This is followed by a Trailers message after processing is complete (and in the case of duplex after receiving stream_end).
  1. Cancellation. At any time between sending the headers and receiving the trailers, the client can send a RequestControl message with a value of cancel that indicates the server should stop processing and send the trailers with a cancellation error.

  2. Deadlines. If a deadline was specified by the client and is exceeded, the server should stop processing and send the trailers with a deadline error.

  3. Errors. At any time after receiving the headers the server may send the trailers with an error code.

  4. Termination.

  • Once the server sends the trailers the communication is over and the pipe may be closed.
  • The Trailers message includes any error code/message if applicable as well as gRPC response trailers.
  • For a successful method call, status_code should be set to 0 (OK) and status_detail to an empty string.
  1. Payloads.
  • A PayloadInfo message includes the number of bytes in the payload as well as an in_same_packet flag.
  • If in_same_packet is true, the bytes of the payload immediately follow the PayloadInfo message.
    • e.g. [ PayloadInfo $payload1 PayloadInfo $payload2 ]
  • If in_same_packet is false, the bytes of the payload are in a separate packet on their own.
    • e.g. [ PayloadInfo PayloadInfo ] [ $payload1 ] [ $payload2 ]
  1. Performance notes. Where possible, multiple messages (aside from large payloads) should be combined into a single packet. Choosing to use a payload in a separate packet should be done for large payloads, e.g. >15 kiB.

  2. Protocol violations. There is no guarantee of client or server behavior if this protocol is violated. (This may be changed in the future.)

  3. Cross-platform support. For Mac/Linux we currently use dotnet's named pipe abstraction which uses a fifo. The protocol is the same except that rather than using message-based transport to delimit packets, instead each packet is prefixed with 4 bytes (using system endianness) that is an int32 indicating the number of subsequent bytes in the packet.

Examples

  • PI = PayloadInfo
  • $x = raw binary payload x

Unary call

Client => [ RequestInit Headers PI $a ]

Server =>                               [ PI $b Trailers ]

Client-streaming call

Client => [ RequestInit Headers ] [ PI $a1 ] [ PI $a2 ] [ stream_end ]

Server =>                                                              [ PI $b Trailers ]

Server-streaming call

Client => [ RequestInit Headers PI $a ]

Server =>                               [ PI $b1 ] [ PI $b2 ] [ Trailers ]

Duplex call

Client => [ RequestInit Headers ] [ PI $a1 ]             [ PI $a2 ] [ stream_end ]

Server =>                                    [ PI $b1 ]                           [ PI $b2 ] [ Trailers ]

Cancellation

Client => [ RequestInit Headers PI $a ] [ cancel ]

Server =>                                          [ Trailers ]

Payload outside packet

Client => [ RequestInit Headers PI ] [ $a ]

Server =>                                   [ PI $b Trailers ]
Clone this wiki locally