gorilla/websocket

Gin实现Web应用

创建Go工程,新增hello.go文件,编写下面代码:

package main

import "fmt"

func main() {
     fmt.Println("Hello, World!")
}

运行可以看到输出结果。下面增加Web服务功能。安装Gin库依赖:

go get -u github.com/gin-gonic/gin

修改上面hello.go文件内容:


package main

import (
  "fmt"

  "github.com/gin-gonic/gin"
)

func main() {
    fmt.Println("Hello, World!")

    // 创建Gin引擎实例
    r := gin.Default()

    // 增加路由ping,简单返回pong
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })

    // listen and serve on 0.0.0.0:8080
    // 启动HTTP服务
    r.Run() 
}
http://localhost:8080/ping
{
"message": "pong"
}

实现WebSocket服务

go get -u github.com/gorilla/websocket

package main

import (
  "fmt"
  "log"
  "net/http"

  "github.com/gin-gonic/gin"
  "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
  // 解决跨域问题
  CheckOrigin: func(r *http.Request) bool {
    return true
  },
} 

func ws(c *gin.Context) {
  //更新get请求使用WebSocket协议
  ws, err := upgrader.Upgrade(c.Writer, c.Request, nil)
  if err != nil {
   log. Print("upgrade:", err)
   return
  }

  defer ws.Close()

  // 监听 ws 消息
  for {
   // 从 ws 读取数据
   mt, message, err := ws.ReadMessage()
   if err != nil {
    log.Println("read:", err)
    break
   }
   log.Printf("recv: %s", message)

   //往 ws 写数据
   err = ws.WriteMessage(mt, message)
   if err != nil {
    log.Println("write:", err)
    break
   }
  }
}

func main() {
    fmt.Println("Websocket Server!")

    r := gin.Default()
    r.GET("/ws", ws)

    r.Run("localhost:8448")
}

核心逻辑为:收到消息后,往客户端写回相同内容。代码增加了注释,主要差异就是for循环中的读写消息。下面需要html文件进行交互,新建index.html文件:

<!DOCTYPE html>
<html lang="en">

<head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Univer Server</title>
</head>

<body>
     <script>
         var ws = new WebSocket("ws://localhost:8448/ws");
         //打开连接时触发
         ws.onopen = function(evt) {
             console.log("Connection open...");
             ws.send("Hello WebSockets!");
         };

         //接收到消息时触发
         ws.onmessage = function(evt) {
             console.log("Received Message: " + evt.data);
         };

         //连接关闭时触发
         ws.onclose = function(evt) {
             console.log("Connection closed.");
         };
     </script>
     Hello WebSocket.
</body>

</html>

script标签中定义了三个回调函数,连接ws后给服务端发送消息,服务端收到消息返回相同内容,最后时关闭连接时触发。

启动测试

go run server.go
python -m http.server 9000
http://localhost:9000/index.html
Connection open...
index.html:21 Received Message: Hello WebSockets!
index.html:25 Connection closed.

首先看到第一行(连接成功打印的日志),然后是接收服务端发送的信息。最后关闭服务端程序,客户端打印连接断开日志。