centrifugo

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Centrifugo 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:
  1. Unidirectional publish (most common): Backend publishes to channels after processing user requests. Clients subscribe and receive updates passively.
  2. Bidirectional with proxy: Clients send data over the real-time connection; Centrifugo proxies events (connect, subscribe, publish, RPC) to the backend for validation.
  3. Server-side subscriptions: Backend controls which channels a user subscribes to (useful for personalized feeds, notifications).
识别要构建的实时功能,选择合适的模式:
  1. 单向发布(最常见):后端处理用户请求后向频道发布消息,客户端订阅后被动接收更新。
  2. 带代理的双向通信:客户端通过实时连接发送数据,Centrifugo 将事件(连接、订阅、发布、RPC)代理到后端进行校验。
  3. 服务端订阅:后端控制用户订阅的频道(适用于个性化 feed、通知场景)。

Step 2: Configure Centrifugo Server

步骤2:配置 Centrifugo 服务器

Generate a minimal configuration:
bash
centrifugo genconfig  # Creates config.json
Or use Docker:
bash
docker run -p 8000:8000 centrifugo/centrifugo:v6 centrifugo
Essential 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
references/configuration.md
for the full configuration reference including TLS, admin UI, environment variables, and advanced options.
生成最简配置:
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
    }
  }
}
阅读
references/configuration.md
获取完整配置参考,包括 TLS、管理后台、环境变量和高级选项。

Step 3: Set Up Authentication

步骤3:设置认证

Centrifugo authenticates clients via JWT or connect proxy.
JWT approach (recommended for most cases):
  • Backend generates a JWT with
    sub
    (user ID) and
    exp
    claims, signed with the configured HMAC/RSA/ECDSA key.
  • Client passes the token when connecting.
  • Supports token refresh for long-lived connections.
python
undefined
Centrifugo 通过 JWT 或连接代理对客户端进行认证。
JWT 方案(大多数场景推荐):
  • 后端生成包含
    sub
    (用户 ID)和
    exp
    声明的 JWT,使用配置的 HMAC/RSA/ECDSA 密钥签名。
  • 客户端连接时携带该 token。
  • 支持长连接的 token 刷新。
python
undefined

Backend: 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
references/authentication.md
for JWT claims, token refresh, proxy auth, and channel-level authorization tokens.
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();
连接代理方案(替代方案):
  • Centrifugo 将连接请求转发到后端端点进行认证。
  • 无需 JWT,后端返回用户身份信息即可。
阅读
references/authentication.md
获取 JWT 声明、token 刷新、代理认证、频道级别授权 token 的相关说明。

Step 4: Design Channel Structure

步骤4:设计频道结构

Channels are ephemeral strings that serve as message pathways. Use namespaces to apply different behaviors.
Naming conventions:
  • chat:room-123
    — namespace
    chat
    , channel for room 123
  • notifications:user#42
    — user-limited channel (only user 42 can subscribe)
  • $private:secret
    — private channel prefix (requires subscription token)
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
references/channels.md
for all channel options, namespace rules, and special channel prefixes.
频道是作为消息通路的临时字符串,可使用命名空间实现不同的行为。
命名规范
  • chat:room-123
    — 命名空间
    chat
    ,对应 123 号房间的频道
  • notifications:user#42
    — 用户专属频道(仅 42 号用户可订阅)
  • $private:secret
    — 私有频道前缀(需要订阅 token)
命名空间配置
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.md
获取所有频道选项、命名空间规则和特殊频道前缀说明。

Step 5: Publish from Backend (Server API)

步骤5:从后端发布消息(服务端 API)

Use HTTP or GRPC to publish messages from the application backend.
HTTP API — POST to
/api/<method>
with
X-API-Key
header:
bash
undefined
使用 HTTP 或 GRPC 从应用后端发布消息。
HTTP API — 携带
X-API-Key
请求头向
/api/<method>
发送 POST 请求:
bash
undefined

Publish 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
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

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

**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

**可用 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:
centrifuge-js
(browser/Node/React Native),
centrifuge-go
,
centrifuge-dart
(Flutter),
centrifuge-swift
(iOS),
centrifuge-java
(Android),
centrifuge-python
.
JavaScript 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:
disconnected
->
connecting
->
connected
(auto-reconnect with exponential backoff).
Subscription states:
unsubscribed
->
subscribing
->
subscribed
(auto-resubscribe on reconnect).
Read
references/client-sdk.md
for all SDK patterns, token refresh, presence/history from client, RPC calls, and Protobuf mode.
官方 SDK:
centrifuge-js
(浏览器/Node/React Native)、
centrifuge-go
centrifuge-dart
(Flutter)、
centrifuge-swift
(iOS)、
centrifuge-java
(Android)、
centrifuge-python
JavaScript 客户端示例
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();
客户端状态
disconnected
->
connecting
->
connected
(指数退避自动重连)。
订阅状态
unsubscribed
->
subscribing
->
subscribed
(重连时自动重新订阅)。
阅读
references/client-sdk.md
获取所有 SDK 使用模式、token 刷新、客户端侧获取在线状态/历史消息、RPC 调用和 Protobuf 模式说明。

Step 7: Configure Event Proxy (Optional)

步骤7:配置事件代理(可选)

Proxy client events to the backend for validation and custom logic.
Supported proxy events:
  • connect
    — authenticate connections without JWT
  • refresh
    — extend client sessions
  • subscribe
    — validate channel access
  • publish
    — validate publications from clients
  • rpc
    — handle custom client-to-server calls
  • sub_refresh
    — extend subscription sessions
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
references/proxy.md
for proxy request/response schemas, GRPC proxy, header forwarding, and timeout configuration.
将客户端事件代理到后端进行校验和自定义逻辑处理。
支持的代理事件
  • connect
    — 无需 JWT 即可认证连接
  • 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"
          }
        }
      }
    ]
  }
}
阅读
references/proxy.md
获取代理请求/响应 schema、GRPC 代理、请求头转发和超时配置说明。

Step 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
references/engines.md
for Redis Sentinel/Cluster setup, sharding, NATS configuration, and separate broker/presence manager configuration.
内存引擎(默认):仅支持单节点,速度快无外部依赖,适合开发和小型部署场景。
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 的替代方案(不支持历史消息/在线状态持久化)。
阅读
references/engines.md
获取 Redis Sentinel/Cluster 搭建、分片、NATS 配置、独立 broker/在线状态管理器配置说明。

Step 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
    +
    history_ttl
    : Define retention window.
  • force_recovery
    : Clients automatically recover missed messages on reconnect.
  • force_positioning
    : Detect publication gaps.
  • Cache recovery mode: Optimized for channels where only the latest state matters. Read
    references/channels.md
    for details.
历史消息可缓存每个频道的最近发布内容,恢复功能可在重连后自动恢复遗漏的消息。
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
/metrics
and supports structured logging.
json
{
  "log_level": "info",
  "prometheus": {
    "enabled": true
  },
  "health": {
    "enabled": true
  }
}
Metrics include: connections, subscriptions, publications, API calls, transport stats, and engine stats.
Centrifugo 在
/metrics
端点暴露 Prometheus 指标,同时支持结构化日志。
json
{
  "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
配置

Empty
allowed_origins
blocks all browser connections. Configure it with the exact origins of the frontend application.
空的
allowed_origins
会阻止所有浏览器连接,请配置为前端应用的精确源地址。

Do 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
exp
claims in JWTs. Too short = excessive refresh requests. Too long = delayed user deactivation. Implement the token refresh callback in client SDKs.
在 JWT 中设置合理的
exp
声明。过短会导致过多的刷新请求,过长会导致用户注销延迟。请在客户端 SDK 中实现 token 刷新回调。

Error Handling

错误处理

  • If the client receives
    102: unknown channel
    — verify the namespace is defined in configuration.
  • If the client receives
    103: permission denied
    — check channel permissions (
    allow_subscribe_for_client
    , subscription JWT, or subscribe proxy).
  • 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
    allowed_origins
    , JWT validity/expiration, and network connectivity.
  • If Redis engine fails to connect — verify address format (
    redis://
    ,
    rediss://
    for TLS,
    redis+sentinel://
    for Sentinel,
    redis+cluster://
    for Cluster).
  • 如果客户端收到
    102: unknown channel
    — 校验配置中是否定义了对应命名空间。
  • 如果客户端收到
    103: permission denied
    — 检查频道权限(
    allow_subscribe_for_client
    、订阅 JWT 或订阅代理配置)。
  • 如果消息未投递 — 校验频道名称完全匹配(包含命名空间前缀),确认至少有一个订阅者存在。
  • 如果出现重连循环 — 检查
    allowed_origins
    、JWT 有效性/过期时间、网络连通性。
  • 如果 Redis 引擎连接失败 — 校验地址格式(普通 Redis 用
    redis://
    、TLS 加密用
    rediss://
    、Sentinel 用
    redis+sentinel://
    、Cluster 用
    redis+cluster://
    )。

Related Integrations

相关集成

Centrifugo integrates well with any backend language/framework. Common setups include:
  • Node.js/Hono/Express: Use HTTP API or
    centrifuge
    npm package for server-side operations.
  • Go: Use the
    centrifuge
    Go library directly or the Centrifugo HTTP/GRPC API.
  • Python/Django/Flask: Use
    pycent
    library or direct HTTP API calls.
  • PHP/Laravel: Use
    phpcent
    library.
For the JavaScript client SDK (
centrifuge-js
), install via npm:
bash
npm install centrifuge
Centrifugo 可与任意后端语言/框架良好集成,常见部署方案包括:
  • Node.js/Hono/Express:使用 HTTP API 或
    centrifuge
    npm 包进行服务端操作。
  • Go:直接使用
    centrifuge
    Go 库或调用 Centrifugo HTTP/GRPC API。
  • Python/Django/Flask:使用
    pycent
    库或直接调用 HTTP API。
  • PHP/Laravel:使用
    phpcent
    库。
对于 JavaScript 客户端 SDK(
centrifuge-js
),可通过 npm 安装:
bash
npm install centrifuge

or

or

bun add centrifuge
undefined
bun add centrifuge
undefined