revel原生支持websocket,需在routes中用ws声明路由(如ws /chat application.chat),action方法接收*websocket.conn参数并手动收发消息;nginx代理时必须配置proxy_http_version 1.1、upgrade和connection头,否则连接60秒后静默断开。

Revel 框架原生支持 WebSocket,但必须手动启用路由、处理连接,并且生产部署时 Nginx 必须显式透传 Upgrade 和 Connection 头,否则连接会在 60 秒后静默断开。
Revel 中如何注册和处理 WebSocket 路由
Revel 不像 Spring Boot 那样自动扫描 @ServerEndpoint,它用 WS 关键字在 conf/routes 文件中声明 WebSocket 端点:
-
WS /chat Application.Chat—— 这行必须存在,且不能写成GET或POST - 对应 action 方法签名必须接收
*websocket.Conn类型参数,例如:func (c App) Chat(ws *websocket.Conn) revel.Result - 需要显式导入
code.google.com/p/go.net/websocket(注意:该包已归档,需用hg下载,Go 1.20+ 用户建议改用golang.org/x/net/websocket替代,但 Revel 2.x 默认未适配,需自行 patch) - Revel 不会自动帮你读/写消息,所有收发都要调用
ws.Write()/ws.Read(),不封装心跳或消息广播逻辑
Nginx 反向代理 WebSocket 时最关键的配置项
默认 Nginx 配置只转发 HTTP 请求,对 WebSocket 升级请求直接拒绝或超时。必须在 location 块中补全三项:
-
proxy_http_version 1.1—— HTTP/1.1 是 Upgrade 机制的前提 -
proxy_set_header Upgrade $http_upgrade—— 把客户端发来的Upgrade: websocket头透传过去 -
proxy_set_header Connection "upgrade"—— 注意是固定字符串"upgrade",不是$connection变量 - 漏掉任意一项,Revel 后端收不到
Sec-WebSocket-Key,websocket.Server初始化失败,浏览器控制台报failed: Error during WebSocket handshake
Revel WebSocket 开发中容易被忽略的边界问题
Revel 的 WebSocket 支持停留在较早期设计,很多现代需求需自行补足:
- 连接生命周期管理:Revel 不提供
onOpen/onClose回调,所有逻辑得塞进 action 函数体里,靠defer+recover捕获 panic 后清理连接 - 并发安全:多个 goroutine 同时对同一
*websocket.Conn调用Write()会 panic,必须加锁或用 channel 序列化写操作 - 无内置鉴权:token 需从 URL 查询参数(如
/chat?token=xxx)或 Cookie 中提取,Revel 不自动解析 WS 握手请求头里的Authorization - 调试困难:Revel 日志默认不打印 WebSocket 握手详情,出错时只能靠抓包看
101 Switching Protocols是否返回
真正卡住人的往往不是“能不能连上”,而是连接建立后消息发不出、收不到、或一并发就 panic —— 这些都指向底层连接状态管理缺失和并发模型误用,而不是框架不支持。











