SoFunction
Updated on 2025-03-02

Demo sharing of websocket usage in Go language

Server code

package main

import (
   "errors"
   "fmt"
   "net/http"
   "sync"
   "time"

   "/gorilla/websocket"
)

// http upgrade websocket protocol configurationvar wsUpgrader = {
   // Allow all CORS cross-domain requests   CheckOrigin: func(r *) bool {
      return true
   },
}

// Client reads and writes messagestype wsMessage struct {
   messageType int
   data        []byte
}

// Client connectiontype wsConnection struct {
   wsSocket * // The underlying websocket   inChan   chan *wsMessage // Read queue   outChan  chan *wsMessage // Write queue
   mutex      // Avoid repeated shutdown of pipelines   isClosed  bool
   closeChan chan byte // Close notification}

func (wsConn *wsConnection) wsReadLoop() {
   for {
      // Read a message      msgType, data, err := ()
      if err != nil {
         goto error
      }
      req := &wsMessage{
         msgType,
         data,
      }
      // Put into the request queue      select {
      case  <- req:
      case <-:
         goto closed
      }
   }
error:
   ()
closed:
}

func (wsConn *wsConnection) wsWriteLoop() {
   for {
      select {
      // Get a response      case msg := <-:
         // Write to websocket         if err := (, ); err != nil {
            goto error
         }
      case <-:
         goto closed
      }
   }
error:
   ()
closed:
}

func (wsConn *wsConnection) procLoop() {
   // Start a gouroutine to send a heartbeat   go func() {
      for { //Continuously writing data to the client, it is the same without it. The client can detect disconnection         (2 * )
         if err := (, []byte("heartbeat from server")); err != nil {
            ("heartbeat fail")
            ()
            break
         }
      }
   }()

   // This is a synchronous processing model (just an example). If you want parallel processing, you can request one gorutine per request. Pay attention to controlling the number of concurrent goroutines!!!   for {
      msg, err := ()
      if err != nil {
         ("read fail")
         break
      }
      (string())
      err = (, ) // After reading the data, write the data synchronously.  It should be written asynchronously      if err != nil {
         ("write fail")
         break
      }
   }
}

func wsHandler(resp , req *) {
   // The answering client informs the upgrade connection to websocket   wsSocket, err := (resp, req, nil)
   if err != nil {
      return
   }
   wsConn := &wsConnection{
      wsSocket:  wsSocket,
      inChan:    make(chan *wsMessage, 1000),
      outChan:   make(chan *wsMessage, 1000),
      closeChan: make(chan byte),
      isClosed:  false,
   }

   // Processor   go ()
   // Read coroutines   go ()
   // Write coroutines   go ()
}

func (wsConn *wsConnection) wsWrite(messageType int, data []byte) error {
   select {
   case  <- &wsMessage{messageType, data}:
   case <-:
      return ("websocket closed")
   }
   return nil
}

func (wsConn *wsConnection) wsRead() (*wsMessage, error) {
   select {
   case msg := <-:
      return msg, nil
   case <-:
   }
   return nil, ("websocket closed")
}

func (wsConn *wsConnection) wsClose() {
   ()

   ()
   defer ()
   if ! {
       = true
      close()
   }
}

func main() {
   ("/ws", wsHandler)
   ("0.0.0.0:7777", nil)
}

Front-end code

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <script>
        ("load", function(evt) {
            const output = ("output");
            const input = ("input");
            let ws;
            const print = function(message) {
                const d = ("div");
                 = message;
                (d);
            };
            ("open").onclick = function(evt) {
                if (ws) {
                    return false;
                }
                ws = new WebSocket("ws://localhost:7777/ws");
                 = function(evt) {
                    print("OPEN");
                }
                 = function(evt) {
                    print("CLOSE");
                    ws = null;
                }
                 = function(evt) {
                    print("RESPONSE: " + );
                }
                 = function(evt) {
                    print("ERROR: " + );
                }
                return false;
            };
            ("send").onclick = function(evt) {
                if (!ws) {
                    return false;
                }
                print("SEND: " + );
                ();
                return false;
            };
            ("close").onclick = function(evt) {
                if (!ws) {
                    return false;
                }
                ();
                return false;
            };
        });
    </script>
</head>
<body>
<table>
    <tr><td valign="top" width="50%">
        <p>Click "Open" to create a connection to the server,
            "Send" to send a message to the server and "Close" to close the connection.
            You can change the message and send multiple times.
        </p>
            <form>
                <button >Open</button>
                <button >Close</button>
            <input  type="text" value="Hello world!">
            <button >Send</button>
            </form>
    </td><td valign="top" width="50%">
        <div ></div>
    </td></tr></table>
</body>
</html>

This is the article about the demo sharing of websocket in Go. For more related websocket content, please search for my previous articles or continue browsing the following related articles. I hope everyone will support me in the future!