Heim  >  Artikel  >  Backend-Entwicklung  >  So entwickeln Sie mithilfe der Go-Sprache ein Echtzeit-Datenübertragungssystem basierend auf Websocket

So entwickeln Sie mithilfe der Go-Sprache ein Echtzeit-Datenübertragungssystem basierend auf Websocket

WBOY
WBOYOriginal
2023-12-18 18:39:46669Durchsuche

So entwickeln Sie mithilfe der Go-Sprache ein Echtzeit-Datenübertragungssystem basierend auf Websocket

So verwenden Sie die Go-Sprache, um ein auf Websocket basierendes Echtzeit-Datenübertragungssystem zu entwickeln. Es sind spezifische Codebeispiele erforderlich.

Websocket ist ein Vollduplex-Protokoll, das eine Echtzeit-Datenübertragung erreichen kann, ohne die Seite zu aktualisieren. In modernen Webanwendungen ist die Datenübertragung in Echtzeit ein entscheidender Bestandteil. In diesem Artikel wird erläutert, wie Sie mithilfe der Go-Sprache ein auf Websocket basierendes Echtzeit-Datenübertragungssystem entwickeln, einschließlich der Implementierung von serverseitigem und clientseitigem Code und stellen spezifische Codebeispiele bereit.

  1. Erstellen Sie einen WebSocket-Server

Um ein Echtzeit-Datenübertragungssystem basierend auf Websocket zu erstellen, müssen Sie zunächst einen Websocket-Server erstellen. In Go können Sie die Gorilla/Websocket-Bibliothek verwenden, um einen Websocket-Server zu erstellen.

Das Folgende ist ein Beispielcode für einen einfachen 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 diesem Beispiel definieren wir zunächst einen Upgrader (Upgrader), der zum Upgrade von HTTP-Verbindungen auf Websocket-Verbindungen verwendet wird. Anschließend definieren wir eine Funktion „serveWs“, die einen HTTP-Antwortschreiber (w) und eine HTTP-Anfrage (r) empfängt und die HTTP-Verbindung auf eine Websocket-Verbindung aktualisiert.

In der ServeWs-Funktion aktualisieren wir zunächst die HTTP-Verbindung auf eine Websocket-Verbindung. Anschließend verwenden wir eine Schleife, um die Websocket-Nachrichten zu lesen. Sobald wir die Nachricht gelesen haben, verarbeiten wir sie und senden dieselbe Nachricht an den Kunden zurück.

Abschließend verknüpfen wir in der Hauptfunktion die Funktion „serveWs“ mit dem Pfad /ws und starten den HTTP-Server auf Port 8080.

  1. Websocket-Client erstellen

Bevor wir den Websocket-Client erstellen, müssen wir eine HTML-Seite erstellen, die über Websocket mit dem Server kommuniziert. Das Folgende ist ein Beispielcode für eine einfache HTML-Seite:

<!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 diesem Beispiel erstellen wir einen Textbereich (Nachricht) und eine Schaltfläche (Senden). Wenn der Benutzer auf die Schaltfläche „Senden“ klickt, senden wir den eingegebenen Text über Websocket an den Server.

In JavaScript verwenden wir das WebSocket-Objekt, um einen Websocket-Client zu erstellen. In unserem Beispiel stellt der Websocket-Client eine Verbindung zum /ws-Pfad her und wenn er Nachrichten vom Server empfängt, gibt er diese an die Konsole aus.

  1. Führen Sie den Websocket-Server und -Client aus.

Um den Websocket-Server und -Client auszuführen, führen Sie die folgenden Schritte aus:

  1. Verwenden Sie in einem Terminal die Befehlszeile, um in das Verzeichnis zu wechseln, das den Beispielservercode enthält.
  2. Geben Sie den folgenden Befehl ein, um den Server zu starten:
go run main.go
  1. Öffnen Sie in Ihrem Browser die folgende URL, um die Beispiel-HTML-Seite zu laden:
http://localhost:8080/
  1. Geben Sie Text in den Textbereich ein und klicken Sie auf die Schaltfläche „Senden“. Sie sollten Nachrichten sehen, die an den Server gesendet und von diesem zurückgegeben werden, und in der Browserkonsole ausgegeben werden.
  2. Echtzeit-Datenübertragung

Jetzt haben wir erfolgreich einen einfachen Websocket-Server und -Client erstellt, aber das ist erst der Anfang. Um eine Echtzeit-Datenübertragung zu erreichen, müssen wir den serverseitigen und clientseitigen Code ändern und auf der Serverseite Goroutine verwenden, um mehrere Websocket-Verbindungen zu verarbeiten.

Das Folgende ist ein Beispielcode, der die Echtzeit-Datenübertragung implementiert:

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 diesem Beispiel definieren wir einen Hub, der mehrere Websocket-Clients verwaltet. Jeder Client verfügt über eine Goroutine zum Lesen (Empfangen) und eine Goroutine zum Schreiben (Senden), die vom Client gelesene Nachrichten bzw. an den Client gesendete Nachrichten verarbeiten.

Neben der Verarbeitung von Client-Nachrichten enthält Hub auch einen Broadcast-Kanal zum Senden von Nachrichten an alle Clients. In unserem Beispiel sendet der Hub regelmäßig das aktuelle Datum und die aktuelle Uhrzeit.

  1. Fazit

Anhand der Codebeispiele in diesem Artikel haben wir gelernt, wie man mit der Go-Sprache ein Echtzeit-Datenübertragungssystem basierend auf Websocket erstellt. Wir haben gelernt, wie man mit der Gorilla/Websocket-Bibliothek einen Websocket-Server und -Client erstellt, und implementiert, wie man mit den Eingaben des Clients umgeht, wie man Nachrichten an den Client sendet, und einen Hub implementiert, der mehrere Websocket-Clients verwaltet, und die Logik von implementiert Broadcast-Nachrichten.

Das obige ist der detaillierte Inhalt vonSo entwickeln Sie mithilfe der Go-Sprache ein Echtzeit-Datenübertragungssystem basierend auf Websocket. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn