-
Notifications
You must be signed in to change notification settings - Fork 48
Wire Protocol
- 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.
- 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
-
- 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.)
- 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 ofstream_end
once there are no more request payloads to be sent.
- Server responses.
- For unary and client-streaming methods, the server sends a
PayloadInfo
message, the response payload, and aTrailers
message after processing is complete (and in the case of client-streaming after receivingstream_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 receivingstream_end
).
-
Cancellation. At any time between sending the headers and receiving the trailers, the client can send a
RequestControl
message with a value ofcancel
that indicates the server should stop processing and send the trailers with a cancellation error. -
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.
-
Errors. At any time after receiving the headers the server may send the trailers with an error code.
-
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.
- 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 ]
- e.g.
- 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 ]
- e.g.
-
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.
-
Protocol violations. There is no guarantee of client or server behavior if this protocol is violated. (This may be changed in the future.)
-
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 ]