Centrifugal client-server protocol definitions and codecs for Go.
This package contains the client-server protocol used by Centrifugo and the Centrifuge library, together with the encoders and decoders they use on hot paths.
The protocol is defined once in client.proto and can be serialized either as JSON or as Protobuf – the two representations are generated from the same definitions, so they never drift apart. Client SDKs in other languages generate their own code from the very same file.
go get github.com/centrifugal/protocolMost applications never import this package directly – they use Centrifugo or Centrifuge, which depend on it. Import it directly when implementing a client, a transport, or tooling that speaks the Centrifugal protocol.
There are three top-level messages:
| Message | Direction | Purpose |
|---|---|---|
Command |
client -> server | Carries exactly one request, e.g. ConnectRequest, SubscribeRequest, PublishRequest. |
Reply |
server -> client | Answers a Command with a result or an Error, or wraps an asynchronous Push. |
Push |
server -> client | Asynchronous message, e.g. Publication, Join, Leave, Disconnect. |
Several messages may be streamed inside a single transport frame. In JSON they are separated by a \n delimiter, in Protobuf each message is prefixed with its length encoded as a varint.
Application payloads (such as Publication.Data) use the Raw type – a []byte passed through encoding as is, so a subscriber decodes the payload its publisher sent. The one exception is required by the JSON framing above and is documented on Raw.MarshalJSON.
Codecs are selected by protocol type and are usually taken from pools to keep the allocation count low:
decoder := protocol.GetCommandDecoder(protocol.TypeJSON, data)
defer protocol.PutCommandDecoder(protocol.TypeJSON, decoder)
for {
cmd, err := decoder.Decode()
if cmd != nil {
// Handle the command.
}
if err != nil {
if errors.Is(err, io.EOF) {
break
}
return err
}
}See the package documentation for the full set of encoders and decoders, and client.proto for the message definitions with comments.
For a description of the protocol from the client point of view see the client protocol documentation on centrifugal.dev.
client.pb.go, client_vtproto.pb.go and client.pb_easyjson.go are generated and committed to the repo. After changing client.proto, regenerate them with:
make generateThe required tools and their pinned versions are listed at the top of generate.sh. Note that the easyjson binary version must match the github.com/mailru/easyjson version in go.mod.
make test # run tests with race detector
make bench # run benchmarks
make fuzz # run fuzz targets for a short time
make lint # run golangci-lint (CI pins its version in .golangci-lint-version)Decoders are fuzzed nightly in CI, see .github/workflows/fuzz.yml.
To report a vulnerability, see SECURITY.md.
MIT, see LICENSE.