Home  >  Article  >  Backend Development  >  How to use Go language to develop a real-time data transmission system based on Websocket

How to use Go language to develop a real-time data transmission system based on Websocket

WBOY
WBOYOriginal
2023-12-18 18:39:46621browse

How to use Go language to develop a real-time data transmission system based on Websocket

How to use Go language to develop a real-time data transmission system based on Websocket, specific code examples are required

Websocket is a full-duplex protocol, which can be used without refreshing the page Achieve real-time data transmission under the circumstances. In modern web applications, real-time data transfer is a crucial part. This article will introduce how to use Go language to develop a real-time data transmission system based on Websocket, including how to implement server-side and client-side code, and provide specific code examples.

  1. Create WebSocket server

To create a real-time data transmission system based on Websocket, you first need to create a Websocket server. In Go, you can use the gorilla/websocket library to create a Websocket server.

The following is a sample code for a simple Websocket server:

package main

import (
    "fmt"
    "net/http"

    "github.com/gorilla/websocket"
)

// 定义升级器
var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}

func serveWs(w http.ResponseWriter, r *http.Request) {
    // 升级请求为Websocket
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println(err)
        return
    }

    // 读取Websocket消息
    for {
        messageType, p, err := conn.ReadMessage()
        if err != nil {
            fmt.Println(err)
            return
        }

        // 处理消息
        fmt.Println(string(p))

        // 回复消息
        err = conn.WriteMessage(messageType, p)
        if err != nil {
            fmt.Println(err)
            return
        }
    }
}

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

In this example, we first define an upgrader (upgrader), which is used to upgrade HTTP connections to Websocket connect. Then, we define a function serveWs that receives an HTTP response writer (w) and HTTP request (r) and upgrades the HTTP connection to a Websocket connection.

In the serveWs function, we first upgrade the HTTP connection to a Websocket connection. We then use a loop to read the Websocket messages. Once we have read the message, we process it and send the same message back to the client.

Finally, in the main function, we associate the serveWs function with the path /ws and start the HTTP server on port 8080.

  1. Create Websocket client

Before creating the Websocket client, we need to create an HTML page that will communicate with the server through Websocket. The following is a sample code for a basic HTML page:

<!DOCTYPE html>
<html>
<head>
    <title>Websocket Example</title>
</head>
<body>

    <textarea id="message"></textarea>
    <button onclick="send()">Send</button>

    <script>
    // 创建Websocket对象
    var ws = new WebSocket("ws://localhost:8080/ws");

    // 接收来自服务器的消息
    ws.onmessage = function(event) {
        console.log(event.data);
    };

    // 发送消息到服务器
    function send() {
        var input = document.getElementById("message");
        ws.send(input.value);
        input.value = "";
    }
    </script>

</body>
</html>

In this example, we create a text area (message) and a button (send). When the user clicks the send button, we send the entered text to the server via Websocket.

In JavaScript, we use the WebSocket object to create a Websocket client. In our example, the Websocket client will connect to the /ws path and when it receives messages from the server, it will output them to the console.

  1. Running Websocket Server and Client

To run Websocket Server and Client, follow these steps:

  1. In the terminal, Use the command line to change to the directory containing the sample server code.
  2. Enter the following command to start the server:
go run main.go
  1. In a browser, open the following URL to load the sample HTML page:
http://localhost:8080/
  1. Enter some text in the text area and click the send button. You should see messages being sent to and returned from the server, and output in the browser console.
  2. Real-time data transmission

Now, we have successfully created a simple Websocket server and client, but this is just the beginning. To achieve real-time data transmission, we need to modify the server-side and client-side code and use goroutine on the server-side to handle multiple Websocket connections.

The following is a sample code that implements real-time data transmission:

package main

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

    "github.com/gorilla/websocket"
)

// 定义升级器
var upgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
}

// 定义客户端
type Client struct {
    conn *websocket.Conn
    send chan []byte
}

// 处理客户端消息
func (c *Client) read() {
    defer func() {
        c.conn.Close()
    }()
    for {
        messageType, p, err := c.conn.ReadMessage()
        if err != nil {
            fmt.Println(err)
            return
        }
        // 处理消息
        fmt.Printf("Received: %s
", p)
    }
}

// 发送消息到客户端
func (c *Client) write() {
    defer func() {
        c.conn.Close()
    }()
    for {
        select {
        case message, ok := <-c.send:
            if !ok {
                c.conn.WriteMessage(websocket.CloseMessage, []byte{})
                return
            }
            writer, err := c.conn.NextWriter(websocket.TextMessage)
            if err != nil {
                return
            }
            writer.Write(message)
            if err := writer.Close(); err != nil {
                return
            }
        }
    }
}

// 定义Hub
type Hub struct {
    clients map[*Client]bool
    broadcast chan []byte
    register chan *Client
    unregister chan *Client
}

// 创建Hub
func newHub() *Hub {
    return &Hub{
        clients:    make(map[*Client]bool),
        broadcast:  make(chan []byte),
        register:   make(chan *Client),
        unregister: make(chan *Client),
    }
}

// 运行Hub
func (h *Hub) run() {
    for {
        select {
        case client := <-h.register:
            h.clients[client] = true
            fmt.Println("Client registered")
        case client := <-h.unregister:
            if _, ok := h.clients[client]; ok {
                delete(h.clients, client)
                close(client.send)
                fmt.Println("Client unregistered")
            }
        case message := <-h.broadcast:
            for client := range h.clients {
                select {
                case client.send <- message:
                    fmt.Printf("Sent: %s
", message)
                default:
                    close(client.send)
                    delete(h.clients, client)
                }
            }
        }
    }
}

func serveWs(hub *Hub, w http.ResponseWriter, r *http.Request) {
    // 升级请求为Websocket
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println(err)
        return
    }

    // 创建客户端
    client := &Client{
        conn: conn,
        send: make(chan []byte),
    }

    // 注册客户端
    hub.register <- client

    // 读取Websocket消息
    go client.read()

    // 发送Websocket消息
    go client.write()
}

func main() {
    // 创建Hub
    hub := newHub()

    // 运行Hub
    go hub.run()

    // 定期广播消息
    go func() {
        for {
            hub.broadcast <- []byte(fmt.Sprintf("Server Time: %s", time.Now().Format("2006-01-02 15:04:05")))
            time.Sleep(1 * time.Second)
        }
    }()

    // 启动HTTP服务器
    http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
        serveWs(hub, w, r)
    })
    http.Handle("/", http.FileServer(http.Dir(".")))
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        panic(err)
    }
}

In this example, we define a Hub that manages multiple Websocket clients. Each client has a read (receive) goroutine and a write (send) goroutine, which handle messages read from the client and messages sent to the client respectively.

In addition to processing client messages, Hub also contains a broadcast channel for broadcasting messages to all clients. In our example, the Hub periodically broadcasts the current date and time.

  1. Conclusion

Through the code examples in this article, we have learned how to use Go language to create a real-time data transmission system based on Websocket. We learned how to use the gorilla/websocket library to create a Websocket server and client, and implemented how to handle the client's input, how to send messages to the client, and implemented a Hub that manages multiple Websocket clients, and implemented The logic of broadcast messages.

The above is the detailed content of How to use Go language to develop a real-time data transmission system based on Websocket. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn