golang Gin framework with websocket

Keywords: Go JSON github Web Development

Summary

For the web development of golang, I have written two blog s before, which respectively introduced:

  1. Under the Gin framework, various http API development methods (including file upload, download, etc.) golang Web solution
  2. Use of reverse proxy in the Gin framework: Use of reverse proxy

Here we add the part of Websocket to the previous Web solution, which can basically cover all the interface types required for daily development

golang websocket Library

The websocket library used here comes from Gorilla web toolkit

The following code shows how to combine websocket API in Gin framework

Example

back-end

The backend provides two kinds of APIs, which respectively support the APIs in the message samples in text format and json format. Each time the API receives a message, it returns 10 times

  1  package main
  2  
  3  import (
  4   "log"
  5   "net/http"
  6   "strconv"
  7   "time"
  8  
  9   "github.com/gin-contrib/static"
 10   "github.com/gin-gonic/gin"
 11   "github.com/gorilla/websocket"
 12  )
 13  
 14  var upGrader = websocket.Upgrader{
 15   CheckOrigin: func(r *http.Request) bool {
 16     return true
 17   },
 18  }
 19  
 20  // webSocket returns text format
 21  func textApi(c *gin.Context) {
 22   //Upgrade get request to webSocket protocol
 23   ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
 24   if err != nil {
 25     log.Println("error get connection")
 26     log.Fatal(err)
 27   }
 28   defer ws.Close()
 29   //Read data in ws
 30   mt, message, err := ws.ReadMessage()
 31   if err != nil {
 32     log.Println("error read message")
 33     log.Fatal(err)
 34   }
 35  
 36   //Write ws data, pong 10 times
 37   var count = 0
 38   for {
 39     count++
 40     if count > 10 {
 41       break
 42     }
 43  
 44     message = []byte(string(message) + " " + strconv.Itoa(count))
 45     err = ws.WriteMessage(mt, message)
 46     if err != nil {
 47       log.Println("error write message: " + err.Error())
 48     }
 49     time.Sleep(1 * time.Second)
 50   }
 51  }
 52  
 53  //webSocket returns json format
 54  func jsonApi(c *gin.Context) {
 55   //Upgrade get request to webSocket protocol
 56   ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
 57   if err != nil {
 58     log.Println("error get connection")
 59     log.Fatal(err)
 60   }
 61   defer ws.Close()
 62   var data struct {
 63     A string `json:"a"`
 64     B int    `json:"b"`
 65   }
 66   //Read data in ws
 67   err = ws.ReadJSON(&data)
 68   if err != nil {
 69     log.Println("error read json")
 70     log.Fatal(err)
 71   }
 72  
 73   //Write ws data, pong 10 times
 74   var count = 0
 75   for {
 76     count++
 77     if count > 10 {
 78       break
 79     }
 80  
 81     err = ws.WriteJSON(struct {
 82       A string `json:"a"`
 83       B int    `json:"b"`
 84       C int    `json:"c"`
 85     }{
 86       A: data.A,
 87       B: data.B,
 88       C: count,
 89     })
 90     if err != nil {
 91       log.Println("error write json: " + err.Error())
 92     }
 93     time.Sleep(1 * time.Second)
 94   }
 95  }
 96  
 97  func websocketGin() {
 98   r := gin.Default()
 99   r.GET("/json", jsonApi)
100   r.GET("/text", textApi)
101  
102   // static files
103   r.Use(static.Serve("/", static.LocalFile("./public", true)))
104  
105   r.NoRoute(func(c *gin.Context) {
106     c.File("./public/index.html")
107   })
108  
109   r.Run(":8000")
110  }

Route r.use (static. Serve ('/', static. Localfile ('. / public, true))) of static files in backend code
Just name the following front-end code index.html and put it in the public folder under the root directory of the back-end code,
After starting the backend, you can access the* http://localhost:8000 "To display the page

Front end

The front-end is very simple, which is to create a websocket connection after the page initialization is completed, and then send a message and display the received message

 1  <!DOCTYPE html>
 2  <html lang="en">
 3    <head>
 4      <meta charset="UTF-8" />
 5      <title>index</title>
 6    </head>
 7    <body>
 8      <h1>test websocket</h1>
 9      <p id="message-json"></p>
10      <p id="message-text"></p>
11      <script>
12        function jsonWS() {
13          var ws = new WebSocket("ws://localhost:8000/json");
14          //Triggered when connection is open
15          ws.onopen = function (evt) {
16            console.log("Connection open ...");
17            var obj = { a: "bb", b: 2 };
18            ws.send(JSON.stringify(obj));
19          };
20          //Triggered when a message is received
21          ws.onmessage = function (evt) {
22            console.log("Received Message: " + evt.data);
23            document.getElementById("message-json").innerText += evt.data;
24          };
25          //Triggered when connection is closed
26          ws.onclose = function (evt) {
27            console.log("Connection closed.");
28          };
29        }
30  
31        function textWS() {
32          var ws = new WebSocket("ws://localhost:8000/text");
33          //Triggered when connection is open
34          ws.onopen = function (evt) {
35            console.log("Connection open ...");
36            ws.send("text message");
37          };
38          //Triggered when a message is received
39          ws.onmessage = function (evt) {
40            console.log("Received Message: " + evt.data);
41            document.getElementById("message-text").innerText = evt.data;
42          };
43          //Triggered when connection is closed
44          ws.onclose = function (evt) {
45            console.log("Connection closed.");
46          };
47        }
48        // Start websocket
49        jsonWS();
50        textWS();
51      </script>
52    </body>
53  </html>

conclusion

After running, you can see the message displayed on the page. If you send the message once, you will receive 10 returns

Posted by EchoFool on Thu, 16 Apr 2020 09:05:42 -0700