sunnyJam 2020-02-16
之所以想要把配置从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,看起来更加清晰了。
完整的代码请见:https://github.com/TomatoMr/awesomeframework。
欢迎关注我的公众号:onepunchgo,给我留言。