Skip to main content

Real-time transports

Centrifugo supports a variety of transports to deliver real-time messages to clients.

Every transport is a persistent connection

Here we describe supported transports between your application frontend and Centrifugo. Every Centrifugo real-time transport is a persistent connection so the server can push data towards clients at any moment.

The important distinction here is that all supported transports belong to one of two possible groups:

Bidirectional

Bidirectional transports are capable to serve all Centrifugo features. These transports are the main Centrifugo focus and where Centrifugo really shines.

Bidirectional transports come with the requirement that developers use a special client connector library (real-time SDK) that communicates with Centrifugo over custom client protocol. This is necessary because bidirectional connections are asynchronous, meaning requests must be matched to their corresponding responses, connection state must be properly managed, and request queueing, timeouts, and errors must be handled. Additionally, the SDK is needed to multiplex subscriptions to different channels over a single connection. Bidirectional SDKs allow binary communication with Centrifugo (using Protobuf protocol).

Centrifugo has several official client real-time SDKs for popular environments. All of them work over WebSocket transport. Our Javascript SDK also offers bidirectional fallbacks over HTTP-Streaming, Server-Sent Events (SSE), and has an experimental support for WebTransport.

Unidirectional

Unidirectional transports suit well for use cases without dynamic subscriptions, where channels to subscribe are known at connection time.

The main advantage is that unidirectional transports do not require special client connectors. Developers can use native browser APIs, such as WebSocket, Server-Sent Events (SSE), or HTTP-streaming), as well as gRPC to receive real-time updates from Centrifugo. This eliminates the need for a client connector that abstracts bidirectional communication.

However, the tradeoff is that with unidirectional transports, you won't get some of Centrifugo's advanced features implemented in bidirectional SDKs, such as dynamic subscriptions/unsubscriptions, automatic message recovery on reconnect, ability to send RPC to the backend over a persistent real-time connection.

At this point, unidirectional transports only support JSON format for communication.

Learn more about unidirectional protocol and available unidirectional transports.

PING/PONG behavior

Centrifugo server periodically sends pings to clients and expects pong from clients that works over bidirectional transports. Sending ping and receiving pong allows to find broken connections faster. Centrifugo sends pings on the Centrifugo client protocol level, thus it's possible for clients to handle ping messages on the client side to make sure connection is not broken (our bidirectional SDKs do this automatically).

Here is a scheme how ping/pong works in bidirectional and unidirectional client scenarios:

By default, Centrifugo sends pings every 25 seconds. This may be changed using client.ping_interval option (duration, default "25s").

Centrifugo expects pong message from bidirectional client SDK after sending ping to it. By default, it waits no more than 8 seconds before closing a connection. This may be changed using client.pong_timeout option (duration, default "8s").

In most cases default ping/pong intervals are fine so you don't really need to tweak them. Reducing timeouts may help you find non-gracefully closed connections faster, but will increase network traffic and CPU resource usage since ping/pongs are sent faster.

caution

When overriding default values make sure that client.ping_interval is greater than client.pong_timeout – this is required by the current server implementation.

Example of configuration:

config.json
{
"client": {
"ping_interval": "25s",
"pong_timeout": "8s"
}
}