Golang-WebSocket

Golang-WebSocket

Pull mode and push mode

The disadvantage of the pull mode is that the data update frequency is low, and most of the requests are invalid, and the number of online users is large, and the query load on the server is high. Regular query and pull cannot meet the timeliness requirements. The push mode only pushes when the data is updated. A large number of online long connections need to be maintained, and the data is pushed immediately after the update.

WebSocket push

Socket programming supported by the browser, easy to maintain the server long connection, based on the TCP reliable transmission protocol, no need for developers to care about the communication details. Provides a highly abstract programming interface and low business development costs.

websocket protocol

From MOOC

After the protocol is upgraded, continue to reuse the bottom layer of HTTP to complete subsequent operations. The bottom layer of the message is split into multiple frame frames for transmission. Programming is to operate only the message and do not need to care about the bottom layer of the frame to complete TCP network I/O, WebSocker protocol analysis, developers do not need to care.

package main

import "net/http"

func wsHandle(writer http.ResponseWriter, request *http.Request) {
      writer.Write([]byte("hello world"))
}

func main() {
    http.HandleFunc("/ws", wsHandle)
    http.ListenAndServe(":8888",nil)
    
}

Service request parameters

Request URL: http://localhost:8888/ws
Request Method: GET
Status Code: 200 OK
Remote Address: [::1]:8888

Server-side code of websocket

package main

import (
    "fmt"
    "github.com/gorilla/websocket"
    "net/http"
    "time"
)

func wsHandle(writer http.ResponseWriter, request *http.Request) {
    upgrader:= websocket.Upgrader{CheckOrigin: func(r *http.Request) bool {
          return true
      }}
    con,err := upgrader.Upgrade(writer,request,nil)
    defer con.Close()
    if err!=nil {
        writer.Write([]byte(err.Error()))
    }
    for{
        _, p, err := con.ReadMessage()
        if err!= nil {
            writer.Write([]byte(err.Error()))
            break
        }
        fmt.Println("client message "+string(p))
        con.WriteMessage(websocket.TextMessage,[]byte(time.Now().String()))
    }
}

func main() {
    http.HandleFunc("/ws", wsHandle)
    http.ListenAndServe(":8888",nil)
    
}

image.png

websocket client code

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <script>
        window.addEventListener("load", function(evt) {
            var output = document.getElementById("output");
            var input = document.getElementById("input");
            var ws;
            var print = function(message) {
                var d = document.createElement("div");
                d.innerHTML = message;
                output.appendChild(d);
            };
            document.getElementById("open").onclick = function(evt) {
                if (ws) {
                    return false;
                }
                ws = new WebSocket("ws://localhost:8888/ws");
                ws.onopen = function(evt) {
                    print("Connect websocket");
                }
                ws.onclose = function(evt) {
                    print("CLOSE");
                    ws = null;
                }
                ws.onmessage = function(evt) {
                    print("Received message: "+ evt.data);
                }
                ws.onerror = function(evt) {
                    print("ERROR: "+ evt.data);
                }
                return false;
            };
            document.getElementById("send").onclick = function(evt) {
                if (!ws) {
                    return false;
                }
                print("Send message: "+ input.value);
                ws.send(input.value);
                return false;
            };
            document.getElementById("close").onclick = function(evt) {
                if (!ws) {
                    return false;
                }
                ws.close();
                return false;
            };
        });
    </script>
</head>
<body>
<table>
    <tr><td valign="top" width="50%">
            <p>Click the start button to create a websocket connection<br/>
               Click the send button to send any message to the server<br/>
               Click the close button to disconnect the websocket connection
            </p>
            <form>
                <button id="open">Start</button>
                <button id="close">Close</button>
                <input id="input" type="text" value="Hello golang!">
                <button id="send">Send</button>
            </form>
        </td><td valign="top" width="50%">
            <div id="output"></div>
        </td></tr></table>
</body>
</html>

Run client.html, the effect is as follows

Data packet capture

Reference: https://cloud.tencent.com/developer/article/1438614 Golang-WebSocket-Cloud + Community-Tencent Cloud