【代码篇】从零开始一步步搭建自己的golang框架(六)

基本上这个基础框架拿到手之后就可以做一些自己想要做的改动了,比如你想添加个队列的插件,你可以在相应的目录里面进行修改了,但我想让它更通用一些,本篇文章将会启动一个websocket服务,并且把配置文件改成yaml格式。

修改配置

之所以想要把配置从json改为yaml,有以下几点原因:

  1. json主要是用于信息传输,而yaml更适合作为配置文件的格式来使用,两者的用途不一样;
  2. yaml格式看起来比json更加清晰;
  3. 在yaml文件中可以添加注释,让配置更加易懂。

在此,解析yaml文件用的包是"gopkg.in/yaml.v2",例子可以在github上找到,文末可以找到本项目的链接。

为框架添加websocket的服务

我希望这个项目能够尽可能地涵盖一些基础的功能,所以我为它添加了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,给我留言。

【代码篇】从零开始一步步搭建自己的golang框架(六)

相关推荐