首先在beego中,我们如何使用websocket呢?
router层:
//websocket服务器
beego.Router("/websocket", &v2.WebSocketController{})
controller层:
type WebSocketController struct {
beego.Controller
}
// Get websocket服务器
func (c *WebSocketController) Get() {
ServeWs(c)
}
// ServeWs handles wsServer requests from the peer.
func ServeWs(c *WebSocketController) {
deliverId := c.GetString("deliverId")
//协议升级
conn, err := upgrader.Upgrade(c.Ctx.ResponseWriter, c.Ctx.Request, nil)
if err != nil {
logger.Z.Error("ws conn failed", zap.String("err", err.Error()))
return
}
client := &Client{conn: conn, send: make(chan []byte, 256), deliverId: deliverId}
MyServer.register <- client
// Allow collection of memory referenced by the caller by doing all work in
// new goroutines.
go client.writePump()
go client.readPump()
}
当客户端访问ws://host:port/websocket?deliverId=XXX(XXX自定义内容,一般为用于标识用户的id)时,就能与服务端建立websocket连接了。
但此时虽然是正常的,但服务端控制台可能会报两个错误:
1. Handler crashed with error can't find templatefile in the path
2. http: response.WriteHeader on hijacked connection from github.com/astaxie/beego/context.(*Response).WriteHeader (context.go:230)
第一个错误,是找不到模版文件,因为在beego中默认是会自动的在调用完相应的 method 方法之后调用 Render 函数,如果你的method是下面这样的,就不会有任何问题:
指定了模版文件,且模版文件存在,而上面我们的websocket的建立是不需要有模版文件的
以JSON的格式返回,此时也不会报找不到模版的错误,但是还是会出现上面说到的第二个问题,就会报:在劫持(hijacked)连接后仍然尝试对其进行HTTP响应写入操作的错误。
解决这两个问题的方法也很简单,网上很多资料说,关闭beego的自动渲染
在app.conf文件配置
autorender = false
或者在main.go代码中修改配置:
beego.BConfig.WebConfig.AutoRender = false
这种方法也是可以的,但是如果你的项目中,存在需要渲染的模版,比如:
这时,程序就不会自动渲染了,需要自己手动渲染c.Render()。
最好的做法是,只需要让某个控制层函数不自动渲染就行了,也十分简单,调用一个函数的事情:
这时,再建立websocket连接的时候就不会再出现报错了,我们的问题也就解决了。