Centrifuge
Real-time messaging library for Go. The simplest way to add feature-rich and scalable WebSocket support to your application. The core of Centrifugo server.
Install / Use
/learn @centrifugal/CentrifugeREADME
This library has no v1 release, API may change. Before v1 release patch version updates only have backwards compatible changes and fixes, minor version updates can have backwards-incompatible API changes. Master branch can have unreleased code. Only two last Go minor versions are officially supported by this library.
The Centrifuge library is a general purpose real-time messaging library for Go programming language. Real-time messaging can help create interactive applications where events are delivered to online users with milliseconds delay. Chats apps, live comments, multiplayer games, real-time data visualizations, telemetry, collaborative tools, etc. can all be built on top of Centrifuge library.
The library is built on top of efficient client-server protocol schema and exposes various real-time oriented primitives for a developer. Centrifuge solves problems developers may come across when building complex real-time applications – like scalability to many server nodes, proper persistent connection management and invalidation, subscription multiplexing, fast reconnect with message recovery, WebSocket fallback options (without sticky sessions requirement in distributed scenario). And it all comes with ready to use client SDKs for both web and mobile development. See the full list of highlighs below.
Centrifuge library is used by:
- Centrifugo - the main product of Centrifugal Labs. Centrifuge was decoupled into separate library from Centrifugo at some point.
- Grafana - the most popular observability platform. Centrifuge library powers Grafana Live subsystem to stream data to panels. See cool demo of WebSocket telemetry from the Assetto Corsa racing simulator to the Grafana dashboard.
Why using Centrifuge
Centrifuge library provides a lot of top of raw WebSocket transport. Important library highlights:
- Fast and optimized for low-latency communication with millions of client connections. See test stand with 1 million connections in Kubernetes
- WebSocket bidirectional transport using JSON or binary Protobuf formats, both based on a strict Protobuf schema. Code generation is used to push both JSON and Protobuf serialization performance to the limits
- Our own WebSocket emulation layer over HTTP-streaming (JSON + Protobuf) and Eventsource (JSON) without sticky sessions requirement for distributed setup
- Possibility to use unidirectional transports without using custom Centrifuge SDK library: see examples for GRPC, EventSource(SSE), HTTP-streaming, Unidirectional WebSocket
- Experimental support for WebSocket over HTTP/2 (RFC 8441), see the examples
- Built-in horizontal scalability with Redis PUB/SUB, consistent Redis sharding, Redis Sentinel and Redis Cluster support, super-optimized Redis communication layer
- Effective non-blocking broadcasts towards client connections using individual queues
- Native authentication over HTTP middleware or custom token-based (ex. JWT)
- Channel concept to broadcast message to all active subscribers
- Client-side and server-side channel subscriptions
- Bidirectional asynchronous message communication, RPC calls, builtin PING/PONG
- Presence information for channels (show all active clients in a channel)
- History information for channels (ephemeral streams with size and TTL retention)
- Join/leave events for channels (aka client goes online/offline)
- Possibility to register a custom PUB/SUB Broker and PresenceManager implementations
- Option to register custom Transport, like Centrifugo does with WebTransport
- Message recovery mechanism for channels to survive PUB/SUB delivery problems, short network disconnects or node restart
- Cache channels – a way to quickly deliver latest publication from channel history to the client upon subscription
- Delta compression using Fossil algorithm for publications inside a channel to reduce bandwidth usage
- Support for client-supplied publication filters to drop unnecessary channel publications on the server side (see the example)
- Per-client and per-channel batching controls for reduced system calls and better CPU utilization
- Out-of-the-box observability using Prometheus instrumentation
- Client SDKs for main application environments all following single behaviour spec (see list of SDKs below).
Real-time SDK
For bidirectional communication between a client and a Centrifuge-based server we have a set of official client real-time SDKs:
- centrifuge-js – for a browser, NodeJS and React Native
- centrifuge-go - for Go language
- centrifuge-dart - for Dart and Flutter
- centrifuge-swift – for native iOS development
- centrifuge-java – for native Android development and general Java
- centrifuge-python - real-time SDK for Python on top of asyncio
- [WIP] centrifuge-csharp - for modern .NET environments (including MAUI, Blazor, Unity)
These SDKs abstract asynchronous communication complexity from the developer: handle framing, reconnect with backoff, timeouts, multiplex channel subscriptions over single connection, etc.
If you opt for a unidirectional communication then you may leverage Centrifuge possibilities without any specific SDK on client-side - simply by using native browser API or GRPC-generated code. See examples of unidirectional communication over GRPC, EventSource(SSE), HTTP-streaming, WebSocket.
Explore Centrifuge
- see Centrifuge Documentation on pkg.go.dev
- read Centrifuge introduction post in Centrifugo blog
- you can also consider Centrifugo server documentation as extra doc for this package (since Centrifugo is built on top of Centrifuge library, though keep in mind that Centrifugo adds some things on top, Centrifugo source code is also a good place to learn from since you can see how to build a production-ready server solution on top of Centrifuge)
- read this README to the end for installation details, quick tutorial and tips and tricks section
- check out examples folder
Installation
go get github.com/centrifugal/centrifuge
Tutorial
Let's take a look on how to build the simplest real-time chat with Centrifuge library. Clients will be able to connect to a server over Websocket, send a message into a channel and this message will be instantly delivered to all active channel subscribers. On a server side we will accept all connections and will work as a simple PUB/SUB proxy without worrying too much about permissions. In this example we will use Centrifuge Javascript client (centrifuge-js) on a frontend.
Start a new Go project and create main.go:
package main
import (
"log"
"net/http"
// Import this library.
"github.com/centrifugal/centrifuge"
)
// Authentication middleware example. Centrifuge expects Credentials
// with current user ID set. Without provided Credentials client
// connection won't be accepted. Another way to authenticate connection
// is reacting to node.OnConnecting event where you may authenticate
// connection based on a custom token sent by a client in first protocol
// frame. See _examples folder in repo to find real-life auth samples
// (OAuth2, Gin sessions, JWT etc).
func auth(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
// Put authentication Credentials into request Context.
// Since we don't have any session backend here we simp
