Build a Simple Websocket Server in Go with Gin

Introduction

The software we use every day, such as chat software, online documents, live broadcast rooms, etc., their back-end services are inseparable from Websocket technology to provide real-time communication capabilities, so how do we use Websocket for real-time back-end services in Go language?

Next, I will use Golang's web development framework Gin, with the Websocket library gorilla/websocket to implement simple back-end services. The following is the implementation process from 0 to 1, suitable for beginners to read.

Solution

Hello World

  1. Install go

https://go.dev/dl/

  1. Create a new directory
mkdir go-websocket-example
cd go-websocket-example
  1. Initialize the project
go mod init github.com/openHacking/go-websocket-example
  1. Create a new file

Create a new hello.go, if you are using the VSCode editor, it will recommend you to install Go-related plug-ins, it is recommended to install it directly

package main

import "fmt"

func main() {
     fmt.Println("Hello, World!")
}
  1. start
go run .

Gin

  1. Install Gin
go get -u github.com/gin-gonic/gin
  1. Import Gin
import "github.com/gin-gonic/gin"
  1. use

Supplement the hello.go code, where the formatting function of the VSCode Go plugin can help you organize the code

package main

import (
  "fmt"

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

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

    r := gin. Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080
}
  1. start

Start the project again

go run .

Then the log will be printed, indicating that the service is started successfully. At this time, open the browser to visit

http://localhost:8080/ping

The server will return JSON

{
"message": "pong"
}

Websocket

  1. Installation
go get -u github.com/gorilla/websocket
  1. Create a new file

Before creating a new one, change the name of the main method in hello.go to hello

Create a new server.go

package main

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

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

var upgrader = websocket. Upgrader{
  // Solve cross-domain problems
  CheckOrigin: func(r *http.Request) bool {
    return true
  },
} // use default options

func ws(c *gin.Context) {
  //Upgrade get request to webSocket protocol
  ws, err := upgrader.Upgrade(c.Writer, c.Request, nil)
  if err != nil {
   log. Print("upgrade:", err)
   return
  }
  defer ws. Close()
  for {
   //read data from ws
   mt, message, err := ws. ReadMessage()
   if err != nil {
    log.Println("read:", err)
    break
   }
   log.Printf("recv: %s", message)

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

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

    bindAddress := "localhost:8448"
    r := gin. Default()
    r.GET("/ws", ws)
    r.Run(bindAddress)
}
  1. start
go run .

Front-end

  1. New HTML

Create a new index.html in the current project or in any directory

<!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");
         //Triggered when the connection is opened
         ws.onopen = function(evt) {
             console.log("Connection open...");
             ws.send("Hello WebSockets!");
         };
         //Triggered when a message is received
         ws.onmessage = function(evt) {
             console.log("Received Message: " + evt.data);
         };
         //Triggered when the connection is closed
         ws.onclose = function(evt) {
             console.log("Connection closed.");
         };
     </script>
</body>

</html>
  1. start

Use VSCode Live Server to start this HTML file

http://127.0.0.1:5500/index.html

The server-side console and browser can see the message sent.

Reference

Comments