十行代码增强Gin处理Websocket的能力
快速开始
最近几年Golang写的比较多,HTTP使用Gin,简单高效。今天我们来增强Gin处理Websocket的能力,先上代码:
package main
import (
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/wonli/aqi"
"github.com/wonli/aqi/ws"
)
func main() {
app := aqi.Init(
aqi.ConfigFile("config.yaml"),
aqi.HttpServer("Aqi", "port"),
)
engine := gin.Default()
// Gin路由
engine.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Hi aqi!")
})
// Websocket入口
engine.GET("/ws", func(c *gin.Context) {
ws.HttpHandler(c.Writer, c.Request)
})
// Websoket路由注册
wsr := ws.NewRouter()
wsr.Add("hi", func(a *ws.Context) {
a.Send(ws.H{
"hi": time.Now(),
})
})
app.WithHttpServer(engine)
app.Start()
}
使用方法很简单,先初始化路由ws.NewRouter()
,然后使用Add方法注册, 最后将engine
作为参数传给app.WithHttpServer(engine)
。这样在愉快的使用gin处理HTTP的时候,也可以愉快的处理Websocket了。
wsr := ws.NewRouter()
wsr.Add("hi", func(a *ws.Context) {
a.Send(ws.H{
"hi": time.Now(),
})
})
我们使用wscat来作为websocket客户端,在terminal中新开一个tab,使用 wscat -c ws://127.0.0.1:2015/ws
与服务端建立连接后,输入{"action":"hi"}
后可以看到服务器返回了当前时间, 运行截图如下:
处理输入参数
我们可以很方便的在业务代码中处理用户输入,接收用户输入的ID再原样返回:
wsr.Add("hi", func(a *ws.Context) {
id := a.GetInt("id")
a.Send(ws.H{
"hi": time.Now(),
"id": id,
})
})
我们已经在业务代码中成功接收和处理输入的ID了
在*ws.Context
中,我们封装了一系列方法来方便的处理输入输出,Get
开头的系列方法获取指定用户输入的参数,比如ID,Name等。Binding
开头系列用于将用户输入转换为一个struct,这是最常用的。Send
开头用于发送数据到客户端,具体请查看代码。
使用中间件
在Aqi
中使用中间件跟Gin类似,先注册一个中间件, 在服务panic的时候收集打印日志,并返回错误码:
package middlewares
import (
"runtime/debug"
"github.com/wonli/aqi/logger"
"github.com/wonli/aqi/ws"
)
func Recovery() ws.HandlerFunc {
return func(a *ws.Context) {
defer func() {
if err := recover(); err != nil {
// 获取 panic 发生的堆栈跟踪
stack := debug.Stack()
logger.SugarLog.Errorf("Panic happened: %s \n %s\n", err, stack)
a.SendCode(30, "服务维护中")
a.Abort()
}
}()
a.Next()
}
}
在业务代码中使用中间件:
wsr := ws.NewRouter()
wsr.Use(middlewares.Recovery()).Add("hi", func(a *ws.Context) {
panic("hi")
})
当然也可以这样:
wsr := ws.NewRouter()
r1 := wsr.Use(middlewares.Recovery())
{
r1.Add("hi", func(a *ws.Context) {
panic("hi")
})
}
当我们程序panic的时候,不会终止进程,而是返回对应的错误信息给客户端,运行截图:
有没有觉得很方便,目前已经开源,感兴趣的小伙伴请点个start吧,希望大家多提意见,一起来完善,谢谢~
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: