centrifugo
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCentrifugo Real-Time Messaging Integration
Centrifugo 实时消息集成
Centrifugo is a self-hosted, language-agnostic real-time messaging server. It handles persistent connections (WebSocket, SSE, HTTP-streaming, WebTransport, GRPC) and broadcasts messages via a channel-based PUB/SUB model. The application backend publishes to channels via Server API; Centrifugo delivers to online subscribers instantly.
Centrifugo 是一款自托管、语言无关的实时消息服务器。它支持处理持久连接(WebSocket、SSE、HTTP-streaming、WebTransport、GRPC),并通过基于频道的 PUB/SUB 模型广播消息。应用后端通过服务端 API 向频道发布消息,Centrifugo 会将消息即时推送给在线订阅者。
Core Architecture
核心架构
Backend App ──(HTTP/GRPC Server API)──> Centrifugo Cluster ──(WebSocket/SSE)──> Clients
│
Redis/NATS Broker
(for multi-node)Key principle: All user-generated data flows through the application backend first (validate, persist, then publish to Centrifugo). Centrifugo is the transport layer, not the source of truth.
Backend App ──(HTTP/GRPC Server API)──> Centrifugo Cluster ──(WebSocket/SSE)──> Clients
│
Redis/NATS Broker
(for multi-node)核心原则:所有用户生成的数据首先流经应用后端(校验、持久化后再发布到 Centrifugo)。Centrifugo 是传输层,而非可信数据源。
Procedures
操作流程
Step 1: Determine Integration Pattern
步骤1:确定集成模式
Identify the real-time feature being built and select the appropriate pattern:
- Unidirectional publish (most common): Backend publishes to channels after processing user requests. Clients subscribe and receive updates passively.
- Bidirectional with proxy: Clients send data over the real-time connection; Centrifugo proxies events (connect, subscribe, publish, RPC) to the backend for validation.
- Server-side subscriptions: Backend controls which channels a user subscribes to (useful for personalized feeds, notifications).
识别要构建的实时功能,选择合适的模式:
- 单向发布(最常见):后端处理用户请求后向频道发布消息,客户端订阅后被动接收更新。
- 带代理的双向通信:客户端通过实时连接发送数据,Centrifugo 将事件(连接、订阅、发布、RPC)代理到后端进行校验。
- 服务端订阅:后端控制用户订阅的频道(适用于个性化 feed、通知场景)。
Step 2: Configure Centrifugo Server
步骤2:配置 Centrifugo 服务器
Generate a minimal configuration:
bash
centrifugo genconfig # Creates config.jsonOr use Docker:
bash
docker run -p 8000:8000 centrifugo/centrifugo:v6 centrifugoEssential configuration structure (JSON, YAML, or TOML supported):
json
{
"client": {
"token": {
"hmac_secret_key": "<SECRET>"
},
"allowed_origins": ["http://localhost:3000"]
},
"http_api": {
"key": "<API_KEY>"
},
"channel": {
"without_namespace": {
"allow_subscribe_for_client": true
}
}
}Read for the full configuration reference including TLS, admin UI, environment variables, and advanced options.
references/configuration.md生成最简配置:
bash
centrifugo genconfig # Creates config.json或者使用 Docker:
bash
docker run -p 8000:8000 centrifugo/centrifugo:v6 centrifugo基础配置结构(支持 JSON、YAML、TOML 格式):
json
{
"client": {
"token": {
"hmac_secret_key": "<SECRET>"
},
"allowed_origins": ["http://localhost:3000"]
},
"http_api": {
"key": "<API_KEY>"
},
"channel": {
"without_namespace": {
"allow_subscribe_for_client": true
}
}
}阅读 获取完整配置参考,包括 TLS、管理后台、环境变量和高级选项。
references/configuration.mdStep 3: Set Up Authentication
步骤3:设置认证
Centrifugo authenticates clients via JWT or connect proxy.
JWT approach (recommended for most cases):
- Backend generates a JWT with (user ID) and
subclaims, signed with the configured HMAC/RSA/ECDSA key.exp - Client passes the token when connecting.
- Supports token refresh for long-lived connections.
python
undefinedCentrifugo 通过 JWT 或连接代理对客户端进行认证。
JWT 方案(大多数场景推荐):
- 后端生成包含 (用户 ID)和
sub声明的 JWT,使用配置的 HMAC/RSA/ECDSA 密钥签名。exp - 客户端连接时携带该 token。
- 支持长连接的 token 刷新。
python
undefinedBackend: generate connection JWT (Python example)
Backend: generate connection JWT (Python example)
import jwt, time
token = jwt.encode(
{"sub": "user123", "exp": int(time.time()) + 3600},
"<HMAC_SECRET>", algorithm="HS256"
)
```javascript
// Client: connect with token
const client = new Centrifuge("ws://localhost:8000/connection/websocket", {
token: "<JWT_TOKEN>",
});
client.connect();Connect proxy approach (alternative):
- Centrifugo forwards connection requests to the backend endpoint for authentication.
- No JWT needed; backend responds with user identity.
Read for JWT claims, token refresh, proxy auth, and channel-level authorization tokens.
references/authentication.mdimport jwt, time
token = jwt.encode(
{"sub": "user123", "exp": int(time.time()) + 3600},
"<HMAC_SECRET>", algorithm="HS256"
)
```javascript
// Client: connect with token
const client = new Centrifuge("ws://localhost:8000/connection/websocket", {
token: "<JWT_TOKEN>",
});
client.connect();连接代理方案(替代方案):
- Centrifugo 将连接请求转发到后端端点进行认证。
- 无需 JWT,后端返回用户身份信息即可。
阅读 获取 JWT 声明、token 刷新、代理认证、频道级别授权 token 的相关说明。
references/authentication.mdStep 4: Design Channel Structure
步骤4:设计频道结构
Channels are ephemeral strings that serve as message pathways. Use namespaces to apply different behaviors.
Naming conventions:
- — namespace
chat:room-123, channel for room 123chat - — user-limited channel (only user 42 can subscribe)
notifications:user#42 - — private channel prefix (requires subscription token)
$private:secret
Namespace configuration:
json
{
"channel": {
"namespaces": [
{
"name": "chat",
"presence": true,
"history_size": 50,
"history_ttl": "300s",
"force_recovery": true,
"join_leave": true
},
{
"name": "notifications",
"allow_user_limited_channels": true
}
]
}
}Read for all channel options, namespace rules, and special channel prefixes.
references/channels.md频道是作为消息通路的临时字符串,可使用命名空间实现不同的行为。
命名规范:
- — 命名空间
chat:room-123,对应 123 号房间的频道chat - — 用户专属频道(仅 42 号用户可订阅)
notifications:user#42 - — 私有频道前缀(需要订阅 token)
$private:secret
命名空间配置:
json
{
"channel": {
"namespaces": [
{
"name": "chat",
"presence": true,
"history_size": 50,
"history_ttl": "300s",
"force_recovery": true,
"join_leave": true
},
{
"name": "notifications",
"allow_user_limited_channels": true
}
]
}
}阅读 获取所有频道选项、命名空间规则和特殊频道前缀说明。
references/channels.mdStep 5: Publish from Backend (Server API)
步骤5:从后端发布消息(服务端 API)
Use HTTP or GRPC to publish messages from the application backend.
HTTP API — POST to with header:
/api/<method>X-API-Keybash
undefined使用 HTTP 或 GRPC 从应用后端发布消息。
HTTP API — 携带 请求头向 发送 POST 请求:
X-API-Key/api/<method>bash
undefinedPublish to a channel
Publish to a channel
curl -X POST -H "X-API-Key: <KEY>" -H "Content-Type: application/json"
-d '{"channel": "chat:room-1", "data": {"text": "hello"}}'
http://localhost:8000/api/publish
-d '{"channel": "chat:room-1", "data": {"text": "hello"}}'
http://localhost:8000/api/publish
curl -X POST -H "X-API-Key: <KEY>" -H "Content-Type: application/json"
-d '{"channel": "chat:room-1", "data": {"text": "hello"}}'
http://localhost:8000/api/publish
-d '{"channel": "chat:room-1", "data": {"text": "hello"}}'
http://localhost:8000/api/publish
Broadcast to multiple channels
Broadcast to multiple channels
curl -X POST -H "X-API-Key: <KEY>" -H "Content-Type: application/json"
-d '{"channels": ["user:1", "user:2"], "data": {"text": "hello"}}'
http://localhost:8000/api/broadcast
-d '{"channels": ["user:1", "user:2"], "data": {"text": "hello"}}'
http://localhost:8000/api/broadcast
**Available API methods**: `publish`, `broadcast`, `subscribe`, `unsubscribe`, `disconnect`, `refresh`, `presence`, `presence_stats`, `history`, `history_remove`, `channels`, `info`, `batch`.
Read `references/server-api.md` for all method signatures, request/response schemas, and HTTP API library links.curl -X POST -H "X-API-Key: <KEY>" -H "Content-Type: application/json"
-d '{"channels": ["user:1", "user:2"], "data": {"text": "hello"}}'
http://localhost:8000/api/broadcast
-d '{"channels": ["user:1", "user:2"], "data": {"text": "hello"}}'
http://localhost:8000/api/broadcast
**可用 API 方法**:`publish`、`broadcast`、`subscribe`、`unsubscribe`、`disconnect`、`refresh`、`presence`、`presence_stats`、`history`、`history_remove`、`channels`、`info`、`batch`。
阅读 `references/server-api.md` 获取所有方法签名、请求/响应 schema 和 HTTP API 库链接。Step 6: Connect Clients with SDK
步骤6:通过 SDK 连接客户端
Official SDKs: (browser/Node/React Native), , (Flutter), (iOS), (Android), .
centrifuge-jscentrifuge-gocentrifuge-dartcentrifuge-swiftcentrifuge-javacentrifuge-pythonJavaScript client pattern:
javascript
import { Centrifuge } from "centrifuge";
const client = new Centrifuge("ws://localhost:8000/connection/websocket", {
token: "<JWT>",
});
// Connection state handlers
client.on("connecting", ctx => console.log("connecting", ctx));
client.on("connected", ctx => console.log("connected", ctx));
client.on("disconnected", ctx => console.log("disconnected", ctx));
// Subscribe to channel
const sub = client.newSubscription("chat:room-1");
sub.on("publication", ctx => {
console.log("received:", ctx.data);
});
sub.on("subscribing", ctx => console.log("subscribing", ctx));
sub.on("subscribed", ctx => console.log("subscribed", ctx));
sub.subscribe();
client.connect();Client states: -> -> (auto-reconnect with exponential backoff).
disconnectedconnectingconnectedSubscription states: -> -> (auto-resubscribe on reconnect).
unsubscribedsubscribingsubscribedRead for all SDK patterns, token refresh, presence/history from client, RPC calls, and Protobuf mode.
references/client-sdk.md官方 SDK:(浏览器/Node/React Native)、、(Flutter)、(iOS)、(Android)、。
centrifuge-jscentrifuge-gocentrifuge-dartcentrifuge-swiftcentrifuge-javacentrifuge-pythonJavaScript 客户端示例:
javascript
import { Centrifuge } from "centrifuge";
const client = new Centrifuge("ws://localhost:8000/connection/websocket", {
token: "<JWT>",
});
// Connection state handlers
client.on("connecting", ctx => console.log("connecting", ctx));
client.on("connected", ctx => console.log("connected", ctx));
client.on("disconnected", ctx => console.log("disconnected", ctx));
// Subscribe to channel
const sub = client.newSubscription("chat:room-1");
sub.on("publication", ctx => {
console.log("received:", ctx.data);
});
sub.on("subscribing", ctx => console.log("subscribing", ctx));
sub.on("subscribed", ctx => console.log("subscribed", ctx));
sub.subscribe();
client.connect();客户端状态: -> -> (指数退避自动重连)。
disconnectedconnectingconnected订阅状态: -> -> (重连时自动重新订阅)。
unsubscribedsubscribingsubscribed阅读 获取所有 SDK 使用模式、token 刷新、客户端侧获取在线状态/历史消息、RPC 调用和 Protobuf 模式说明。
references/client-sdk.mdStep 7: Configure Event Proxy (Optional)
步骤7:配置事件代理(可选)
Proxy client events to the backend for validation and custom logic.
Supported proxy events:
- — authenticate connections without JWT
connect - — extend client sessions
refresh - — validate channel access
subscribe - — validate publications from clients
publish - — handle custom client-to-server calls
rpc - — extend subscription sessions
sub_refresh
json
{
"client": {
"proxy": {
"connect": {
"enabled": true,
"endpoint": "http://backend:3000/centrifugo/connect"
},
"rpc": {
"enabled": true,
"endpoint": "http://backend:3000/centrifugo/rpc"
}
}
},
"channel": {
"namespaces": [
{
"name": "chat",
"proxy": {
"subscribe": {
"enabled": true,
"endpoint": "http://backend:3000/centrifugo/subscribe"
},
"publish": {
"enabled": true,
"endpoint": "http://backend:3000/centrifugo/publish"
}
}
}
]
}
}Read for proxy request/response schemas, GRPC proxy, header forwarding, and timeout configuration.
references/proxy.md将客户端事件代理到后端进行校验和自定义逻辑处理。
支持的代理事件:
- — 无需 JWT 即可认证连接
connect - — 延长客户端会话
refresh - — 校验频道访问权限
subscribe - — 校验客户端发布的消息
publish - — 处理自定义的客户端到服务端调用
rpc - — 延长订阅会话
sub_refresh
json
{
"client": {
"proxy": {
"connect": {
"enabled": true,
"endpoint": "http://backend:3000/centrifugo/connect"
},
"rpc": {
"enabled": true,
"endpoint": "http://backend:3000/centrifugo/rpc"
}
}
},
"channel": {
"namespaces": [
{
"name": "chat",
"proxy": {
"subscribe": {
"enabled": true,
"endpoint": "http://backend:3000/centrifugo/subscribe"
},
"publish": {
"enabled": true,
"endpoint": "http://backend:3000/centrifugo/publish"
}
}
}
]
}
}阅读 获取代理请求/响应 schema、GRPC 代理、请求头转发和超时配置说明。
references/proxy.mdStep 8: Scale Horizontally (Production)
步骤8:水平扩展(生产环境)
Memory engine (default): Single node only. Fast, no dependencies. Suitable for development and small deployments.
Redis engine: Multi-node clusters. Messages published on any node reach all subscribers.
json
{
"engine": {
"type": "redis",
"redis": {
"address": "redis://localhost:6379"
}
}
}Supports Redis Sentinel, Redis Cluster, consistent sharding across multiple Redis instances, and Redis-compatible storages (Valkey, DragonflyDB, KeyDB, AWS ElastiCache).
NATS broker: Alternative for PUB/SUB only (no history/presence persistence).
Read for Redis Sentinel/Cluster setup, sharding, NATS configuration, and separate broker/presence manager configuration.
references/engines.md内存引擎(默认):仅支持单节点,速度快无外部依赖,适合开发和小型部署场景。
Redis 引擎:支持多节点集群,任意节点发布的消息可送达所有订阅者。
json
{
"engine": {
"type": "redis",
"redis": {
"address": "redis://localhost:6379"
}
}
}支持 Redis Sentinel、Redis Cluster、多 Redis 实例一致性分片,以及兼容 Redis 的存储(Valkey、DragonflyDB、KeyDB、AWS ElastiCache)。
NATS broker:仅用于 PUB/SUB 的替代方案(不支持历史消息/在线状态持久化)。
阅读 获取 Redis Sentinel/Cluster 搭建、分片、NATS 配置、独立 broker/在线状态管理器配置说明。
references/engines.mdStep 9: Enable History and Recovery
步骤9:启用历史消息和恢复功能
History allows caching recent publications per channel. Recovery automatically restores missed messages after reconnection.
json
{
"channel": {
"namespaces": [
{
"name": "chat",
"history_size": 100,
"history_ttl": "600s",
"force_recovery": true,
"force_positioning": true
}
]
}
}- +
history_size: Define retention window.history_ttl - : Clients automatically recover missed messages on reconnect.
force_recovery - : Detect publication gaps.
force_positioning - Cache recovery mode: Optimized for channels where only the latest state matters. Read for details.
references/channels.md
历史消息可缓存每个频道的最近发布内容,恢复功能可在重连后自动恢复遗漏的消息。
json
{
"channel": {
"namespaces": [
{
"name": "chat",
"history_size": 100,
"history_ttl": "600s",
"force_recovery": true,
"force_positioning": true
}
]
}
}- +
history_size:定义消息保留窗口。history_ttl - :客户端重连时自动恢复遗漏的消息。
force_recovery - :检测发布消息缺口。
force_positioning - 缓存恢复模式:针对仅需最新状态的频道优化,阅读 获取详情。
references/channels.md
Step 10: Add Observability
步骤10:添加可观测性
Centrifugo exposes Prometheus metrics at and supports structured logging.
/metricsjson
{
"log_level": "info",
"prometheus": {
"enabled": true
},
"health": {
"enabled": true
}
}Metrics include: connections, subscriptions, publications, API calls, transport stats, and engine stats.
Centrifugo 在 端点暴露 Prometheus 指标,同时支持结构化日志。
/metricsjson
{
"log_level": "info",
"prometheus": {
"enabled": true
},
"health": {
"enabled": true
}
}指标包括:连接数、订阅数、发布数、API 调用量、传输统计、引擎统计。
Anti-Patterns
反模式
Do NOT use Centrifugo history as a primary database
不要将 Centrifugo 历史消息作为主数据库
History is an ephemeral hot cache designed to reduce database load during reconnect storms. Always maintain a primary application database.
历史消息是临时热缓存,设计目的是降低重连风暴时的数据库负载。请始终维护独立的应用主数据库。
Do NOT rely solely on Centrifugo for data delivery
不要完全依赖 Centrifugo 进行数据投递
Design with graceful degradation. If Centrifugo goes down, the application should still function (just without real-time updates). Return data in API responses, not only via channels.
设计时要考虑优雅降级。如果 Centrifugo 宕机,应用仍应可正常运行(仅缺少实时更新)。在 API 响应中返回数据,而不是仅通过频道推送。
Do NOT skip allowed_origins
in production
allowed_origins生产环境不要省略 allowed_origins
配置
allowed_originsEmpty blocks all browser connections. Configure it with the exact origins of the frontend application.
allowed_origins空的 会阻止所有浏览器连接,请配置为前端应用的精确源地址。
allowed_originsDo NOT publish directly from clients without proxy validation
没有经过代理校验不要允许客户端直接发布消息
Always validate client publications through either:
- The application backend (clients call backend API, backend publishes to Centrifugo), or
- Publish proxy (Centrifugo forwards client publish to backend for validation)
始终通过以下两种方式之一校验客户端发布的内容:
- 应用后端(客户端调用后端 API,后端再发布到 Centrifugo),或者
- 发布代理(Centrifugo 将客户端发布请求转发到后端校验)
Do NOT use channels without namespaces in production
生产环境不要使用无命名空间的频道
Namespaces provide granular control over channel behavior and permissions. Define a namespace for each real-time feature.
命名空间可对频道行为和权限进行细粒度控制,请为每个实时功能定义单独的命名空间。
Do NOT ignore token expiration
不要忽略 token 过期时间
Set reasonable claims in JWTs. Too short = excessive refresh requests. Too long = delayed user deactivation. Implement the token refresh callback in client SDKs.
exp在 JWT 中设置合理的 声明。过短会导致过多的刷新请求,过长会导致用户注销延迟。请在客户端 SDK 中实现 token 刷新回调。
expError Handling
错误处理
- If the client receives — verify the namespace is defined in configuration.
102: unknown channel - If the client receives — check channel permissions (
103: permission denied, subscription JWT, or subscribe proxy).allow_subscribe_for_client - If publications are not delivered — verify the channel name matches exactly (namespace prefix included). Ensure at least one subscriber exists.
- If reconnection loops occur — check , JWT validity/expiration, and network connectivity.
allowed_origins - If Redis engine fails to connect — verify address format (,
redis://for TLS,rediss://for Sentinel,redis+sentinel://for Cluster).redis+cluster://
- 如果客户端收到 — 校验配置中是否定义了对应命名空间。
102: unknown channel - 如果客户端收到 — 检查频道权限(
103: permission denied、订阅 JWT 或订阅代理配置)。allow_subscribe_for_client - 如果消息未投递 — 校验频道名称完全匹配(包含命名空间前缀),确认至少有一个订阅者存在。
- 如果出现重连循环 — 检查 、JWT 有效性/过期时间、网络连通性。
allowed_origins - 如果 Redis 引擎连接失败 — 校验地址格式(普通 Redis 用 、TLS 加密用
redis://、Sentinel 用rediss://、Cluster 用redis+sentinel://)。redis+cluster://
Related Integrations
相关集成
Centrifugo integrates well with any backend language/framework. Common setups include:
- Node.js/Hono/Express: Use HTTP API or npm package for server-side operations.
centrifuge - Go: Use the Go library directly or the Centrifugo HTTP/GRPC API.
centrifuge - Python/Django/Flask: Use library or direct HTTP API calls.
pycent - PHP/Laravel: Use library.
phpcent
For the JavaScript client SDK (), install via npm:
centrifuge-jsbash
npm install centrifugeCentrifugo 可与任意后端语言/框架良好集成,常见部署方案包括:
- Node.js/Hono/Express:使用 HTTP API 或 npm 包进行服务端操作。
centrifuge - Go:直接使用 Go 库或调用 Centrifugo HTTP/GRPC API。
centrifuge - Python/Django/Flask:使用 库或直接调用 HTTP API。
pycent - PHP/Laravel:使用 库。
phpcent
对于 JavaScript 客户端 SDK(),可通过 npm 安装:
centrifuge-jsbash
npm install centrifugeor
or
bun add centrifuge
undefinedbun add centrifuge
undefined