centrifugo服务端必须启用websocket和jwt验证,否则连接被拒且日志无明确原因;需配置--jwt_secret、jwt_issuer、jwt_audience一致,正确设置websocket路径及nginx透传头,token须用hs256签名并含exp/user/info字段,前端通过auth.token传入,弹幕发布须调用http api而非sdk。

Centrifugo 服务端配置必须启用 WebSocket 和 JWT 验证
Centrifugo 默认不开启 JWT 验证,但 Golang 后端若要安全地生成连接 token,必须让 Centrifugo 处于 JWT 模式。否则前端拿到的 token 无法通过验证,连接会直接被拒绝,错误日志里只显示 connection rejected,没有具体原因。
- 启动 Centrifugo 时加参数:
--jwt_secret=your_secret_key(生产环境务必用强随机密钥) - 确保配置文件中
jwt_issuer和jwt_audience与后端签发 token 时一致(如都设为空或都设为"centrifugo") - WebSocket 端点默认是
/connection/websocket,别写成/websocket或漏掉/connection/前缀 - 如果用 Nginx 反向代理,需显式透传 Upgrade / Connection 头,否则 WebSocket 握手失败,浏览器报错
WebSocket opening handshake was canceled
Go 后端用 github.com/centrifugal/centrifuge-go 签发 token
官方推荐的 Go SDK centrifuge-go 仅用于构建自托管 Centrifugo(即嵌入式模式),**不能用来签发连接 token**。真正该用的是 JWT 库手动签发,且 payload 格式必须严格匹配 Centrifugo 要求。
- token payload 至少包含:
exp(Unix 时间戳,建议 10 分钟内过期)、user(字符串用户 ID)、info(可选 JSON 字符串,比如昵称、头像 URL) - 签名算法只能用
HS256,密钥必须和 Centrifugo 启动时的--jwt_secret完全一致 - 示例关键代码:
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "exp": time.Now().Add(10 * time.Minute).Unix(), "user": "u_123456", "info": `{"nick":"张三","avatar":"https://..."}`, }) - 别用
github.com/golang-jwt/jwt/v5的新版本——它默认禁用unsafeAllowNoneSignatureType,但 Centrifugo 不接受none算法;老版本v3更稳,或显式配置v4/v5的 signing method
前端连接时必须传入正确的 connection JWT 参数
Centrifugo JS SDK 的 connect 方法不接受 raw token 字符串,而是要求把 token 放在 auth 字段里,且整个参数对象结构不能错,否则 token 根本不会被发送到服务端。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 正确调用方式:
const centrifuge = new Centrifuge('wss://your-domain.com/connection/websocket', { auth: { token: 'eyJhbGciOiJIUzI1Ni...' }, }); - 如果用了自定义
authEndpoint,注意它返回的响应体必须是 JSON,且顶层字段为token,不是data.token或其他嵌套结构 - 开发时可用
centrifuge.setDebug(true)查看控制台里是否发出connect请求、是否有auth字段、服务端返回的error具体内容是什么 - 别在浏览器 localStorage 里硬编码 token——过期后连接断开,前端不会自动重连并刷新 token,得自己实现
onDisconnect+refresh逻辑
弹幕消息发布必须走 Centrifugo HTTP API,而非直接调用 SDK
Golang 后端发弹幕,不是调用某个 SDK 的 Publish 方法,而是发一个带认证的 POST 请求到 Centrifugo 的 HTTP API。本地直连或用 SDK 封装只是省事,底层全是 HTTP。
- API 地址是
http://localhost:8000/api(默认),方法 POST,Header 加Authorization: apikey your_api_key - 请求体必须是 JSON:
{"method": "publish", "params": {"channel": "room:1001", "data": {"text": "Hello!", "uid": "u_123456"}} -
apikey是启动 Centrifugo 时用--api_key=xxx设置的,和 JWT secret 完全无关,别混淆 - channel 名必须以字母开头,支持
:和_,但不能含空格或 Unicode 控制字符,否则 publish 返回invalid channel format - 如果用 Gin/Echo 处理弹幕提交,记得对
data字段做长度限制(比如 ≤ 500 字符)和敏感词过滤,Centrifugo 本身不做业务校验
实际跑通的关键不在“怎么连”,而在于三端 token 流程是否闭环:Go 签的 token 能被 Centrifugo 解出来、前端带着它能完成 WebSocket 握手、后端发消息时 channel 和权限配置刚好匹配订阅关系。漏掉任意一环,现象都是“看起来连上了,但收不到消息”。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










