基本上这个基础框架拿到手之后就可以做一些自己想要做的改动了,比如你想添加个队列的插件,你可以在相应的目录里面进行修改了,但我想让它更通用一些,本篇文章将会启动一个websocket服务,并且把配置文件改成yaml格式。
之所以想要把配置从json改为yaml,有以下几点原因:
在此,解析yaml文件用的包是"gopkg.in/yaml.v2",例子可以在github上找到,文末可以找到本项目的链接。
我希望这个项目能够尽可能地涵盖一些基础的功能,所以我为它添加了websocket的接口,来看看我具体是怎么做的。
之前说过本项目的具体处理逻辑都会在process/controller下进行,而接口层面则是在http和rpc目录下去分发。在添加websocket进到这个框架之前,我们要先知道一点:websocket是一种协议,一种在http上升级的协议,所以它并不像我们之前开启http服务一样,直接监听端口,而是在http服务上开一个接口,通过接口去实现服务端与客户端的连接,好了,明确了这一点之后,我们来看看代码方面如何实现。
首先,我们添加一个路由。
engine.GET("/ws", Ws)
然后,实现路由指向的handler--Ws。
func Ws(ctx *gin.Context) {
ws, err := upGrader.Upgrade(ctx.Writer, ctx.Request, nil)
if err != nil {
return
}
defer ws.Close()
for {
//读取数据
mt, message, err := ws.ReadMessage()
if err != nil {
break
}
if string(message) == "ping" {
message = []byte("pong")
}
if string(message) == "server_time" {
resp, _, _ := controller.GetServerTime()
serverTime := strconv.FormatInt(resp.ServerTime, 10)
message = []byte(serverTime)
}
//写入数据
err = ws.WriteMessage(mt, message)
if err != nil {
break
}
}
}
注意一下,这一句代码:
ws, err := upGrader.Upgrade(ctx.Writer, ctx.Request, nil)
前面说了,websocket是一个协议,一个http之上的协议,因此,我们对http“升级”了。代码中还用了一个for循环,这就很像是http的监听一样。为了统一,我们调用了controller.GetServerTime()来获取系统时间,这就让http接口和ws接口都统一了,真正的实现逻辑都在controller。
再来,我们写一个客户端来测试:
func TestWs(t *testing.T) {
var dialer *websocket.Dialer
conn, _, err := dialer.Dial("ws://127.0.0.1:8080/ws", nil)
if err != nil {
fmt.Println(err)
return
}
go timeWriter(conn)
for {
_, message, err := conn.ReadMessage()
if err != nil {
fmt.Println("read:", err)
return
}
fmt.Printf("received: %s\n", message)
}
}
func timeWriter(conn *websocket.Conn) {
for {
time.Sleep(time.Second * 2)
conn.WriteMessage(websocket.TextMessage, []byte(time.Now().Format("2006-01-02 15:04:05")))
conn.WriteMessage(websocket.TextMessage, []byte("ping"))
conn.WriteMessage(websocket.TextMessage, []byte("server_time"))
}
}
到此为止,我们就为这个框架添加了websocket的功能,并且把配置文件的格式从json改为了yaml,看起来更加清晰了。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。