Heim  >  Artikel  >  Backend-Entwicklung  >  So implementieren Sie Multithread-Websocket-Kommunikation mithilfe der Go-Sprache

So implementieren Sie Multithread-Websocket-Kommunikation mithilfe der Go-Sprache

WBOY
WBOYOriginal
2023-12-14 13:45:441106Durchsuche

So implementieren Sie Multithread-Websocket-Kommunikation mithilfe der Go-Sprache

In den letzten Jahren ist Echtzeitkommunikation zu einem Grundbedürfnis geworden. WebSocket ist führend in der Echtzeitkommunikation und kann die Echtzeitkommunikation zwischen Client und Server schneller und effektiver realisieren. Auch die Go-Sprache ist in den letzten Jahren zu einer beliebten Sprache geworden und wird häufig in der Echtzeitkommunikation verwendet. Durch die Nutzung der Vorteile der Go-Sprache und der Eigenschaften der Multithread-Verarbeitung kann die Kommunikationsfunktion von Websocket effizienter und stabiler realisiert werden.

Dieser Artikel konzentriert sich auf die Go-Sprache und stellt vor, wie man sie zur Implementierung der Multithread-Websocket-Kommunikation verwendet, einschließlich einiger wichtiger Funktionsimplementierungen, und stellt detaillierte Codebeispiele bereit.

Websocket implementieren

Bevor Sie die Go-Sprache zum Implementieren der Websocket-Kommunikation verwenden, müssen Sie einige Grundkenntnisse der Websocket-Kommunikation verstehen. Websocket ist wie HTTP ein Netzwerkprotokoll, das auf TCP basiert. Der Unterschied besteht jedoch darin, dass es sich nicht um einen Anforderungs- und Antwortmodus handelt, sondern um eine kontinuierliche Verbindung zwischen dem Client und dem Server, die eine Echtzeitkommunikation zwischen den beiden Parteien ermöglicht.

In der Go-Sprache besteht der erste Schritt zur Implementierung der Websocket-Kommunikation darin, die Pakete „net/http“ und „github.com/gorilla/websocket“ zu importieren. Unter anderem wird „net/http“ zum Erstellen eines HTTP-Servers verwendet und „github.com/gorilla/websocket“ ist ein Drittanbieterpaket für Websocket. Wenn dieses Paket nicht verfügbar ist, können Sie es mit dem Befehl „go get“ installieren.

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

Erstellen Sie eine Websocket-Verbindung

Verwenden Sie die Methode „http.HandleFunc()“, um eine Websocket-Verbindung in der Go-Sprache einzurichten, wie unten gezeigt:

func main() {
    http.HandleFunc("/", handleConnections)

    http.ListenAndServe(":4000", nil)
}

Der obige Code verwendet zum Erstellen die Methode „http.HandleFunc()“. eine Verbindungsverarbeitungsfunktion namens „handleConnections“, die für den Aufbau einer Websocket-Verbindung verantwortlich ist. Wie Sie sehen können, ist der Anforderungspfad zum Herstellen einer Websocket-Verbindung „/“, das Stammverzeichnis.

Verbindungsanfragen verarbeiten

Nach dem Herstellen einer Websocket-Verbindung müssen Sie einige grundlegende Parameter für die Verbindungsanfrage konfigurieren, z. B. Protokollaktualisierung, Lese- und Schreibcachegröße, Heartbeat-Timeout usw.

var upgrader = websocket.Upgrader{
    ReadBufferSize: 1024,
    WriteBufferSize: 1024,
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

Der obige Code wird mit „websocket.Upgrader“ konfiguriert, wobei „ReadBufferSize“ und „WriteBufferSize“ die Größe des Lese- und Schreibpuffers angeben und „CheckOrigin“ auf „true“ gesetzt ist, was angibt, dass alle Quellzugriffsanforderungen vorliegen sind akzeptiert. Wenn eine bestimmte Quelle erforderlich ist, kann diese entsprechend den spezifischen Anforderungen eingestellt werden.

Verarbeitung von Verbindungsanfragen

Nachdem die Websocket-Verbindungsanforderung verarbeitet wurde, muss für die Protokollaktualisierung der Standard-Websocket-Protokoll-Handshake befolgt werden. In der Go-Sprache kann das Protokoll-Upgrade den Upgrader verwenden, um einen Protokoll-Handshake durchzuführen und das Verbindungs-Handle (conn) zurückzugeben, um Nachrichten während des Lebenszyklus der Websocket-Verbindung zu senden und zu empfangen.

func handleConnections(w http.ResponseWriter, r *http.Request) {
    // 通过Upgrader进行协议升级
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println(err)
    }

    // 若协议升级成功,则跳转到另一个处理函数处理消息
    go handleMessages(ws)
}

In der handleConnections-Funktion wird das Protokoll zunächst über den Upgrader aktualisiert. Wenn das Upgrade erfolgreich ist, rufen Sie „go handleMessages(ws)“ auf, um Goroutine zu starten und mit der Verarbeitung von Websocket-Nachrichten zu beginnen.

Websocket-Nachrichten verarbeiten

Der nächste Schritt besteht darin, die Websocket-Nachrichten zu verarbeiten. In der Go-Sprache können Sie eine Endlosschleife verwenden, um den Eingang von Websocket-Nachrichten zu überwachen und dann jede Nachricht entsprechend zu verarbeiten.

func handleMessages(ws *websocket.Conn) {
    for {
        messageType, p, err := ws.ReadMessage()
        if err != nil {
            fmt.Println(err)
            return
        }

        // 根据消息类型进行处理
        switch messageType {
        case websocket.TextMessage:
            // 处理text类型消息
            fmt.Println(string(p))
        case websocket.BinaryMessage:
            // 处理binary类型消息
            fmt.Println(p)
        }
    }
}

In der Funktion handleMessages verwenden Sie zunächst die Methode „ws.ReadMessage()“, um die Websocket-Nachricht zu lesen und entsprechend dem Nachrichtentyp zu verarbeiten.

Websocket-Nachricht senden

Der letzte Teil ist der Sendeteil der Websocket-Nachricht. In der Go-Sprache können Sie das Websocket-Verbindungshandle „ws“ verwenden, um Daten an den Client zu senden.

func sendMessage(ws *websocket.Conn, messageType int, message []byte) error {
    if err := ws.WriteMessage(messageType, message); err != nil {
        return err
    }

    return nil
}

In der sendMessage-Funktion senden Sie zunächst die Nachricht über die Methode „ws.WriteMessage()“ an den Client.

Multithread-Websocket-Verarbeitung

Um die Effizienz der Websocket-Kommunikation zu verbessern, muss Multithreading zur Verarbeitung von Websocket-Nachrichten verwendet werden. In der Go-Sprache können Sie Goroutine verwenden, um die gleichzeitige Verarbeitung zu implementieren.

Goroutine starten

In der Go-Sprache ist das Starten einer Goroutine sehr einfach. Fügen Sie einfach „go“ vor der Funktion hinzu.

go handleMessages(ws)

Broadcast-Nachricht

In der tatsächlichen Entwicklung muss Websocket normalerweise Broadcast-Nachrichten implementieren, dh eine Nachricht an alle verbundenen Clients senden. In der Go-Sprache können Sie eine Karte verwenden, um alle verbundenen Clients zu speichern und diese dann zu durchlaufen und nacheinander Nachrichten an jeden Client zu senden.

var clients = make(map[*websocket.Conn]bool) // 所有连接的客户端
var broadcast = make(chan []byte) // 广播通道

func main() {
    http.HandleFunc("/", handleConnections)
    go handleMessages()

    http.ListenAndServe(":4000", nil)
}

func handleConnections(w http.ResponseWriter, r *http.Request) {
    // 通过Upgrader进行协议升级
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println(err)
    }

    // 若协议升级成功,则将客户端存入map
    clients[ws] = true
}

func handleMessages() {
    for {
        // 从广播通道中获取消息
        message := <- broadcast
        // 对所有连接的客户端发送消息
        for client := range clients {
            if err := client.WriteMessage(websocket.TextMessage, message); err != nil {
                fmt.Println(err)
                delete(clients, client)
                return
            }
        }
    }
}

Im obigen Code ist ein Broadcast-Kanal (Broadcast) implementiert, um Broadcast-Nachrichten zu verarbeiten. Gleichzeitig wird eine Karte (Clients) erstellt, in der alle angeschlossenen Clients gespeichert werden. Wenn in der Funktion handleConnections ein neuer Client eine Verbindung herstellt, wird dies in den Clients gespeichert. In der Funktion handleMessages erhält der Broadcast-Kanal neue Nachrichten von ihm und sendet diese an alle verbundenen Clients.

Gewährleistung der Parallelitätssicherheit

Während Multithreading Websocket-Nachrichten verarbeitet, ist es notwendig, die Sicherheit der Datenparallelität zu gewährleisten. In der Go-Sprache können Sie Sperren zur Sicherheitskontrolle der Parallelität verwenden. Im Beispielcode dieses Artikels wird „sync.RWMutex“ verwendet, um Lese-/Schreibsperren zu implementieren, um die Sicherheit der Parallelität zu gewährleisten.

var mutex = &sync.RWMutex{}

func handleConnections(w http.ResponseWriter, r *http.Request) {
    // 通过Upgrader进行协议升级
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println(err)
    }

    // 若协议升级成功,则将客户端存入map,并进行锁定
    mutex.Lock()
    clients[ws] = true
    mutex.Unlock()
}

func handleMessages() {
    for {
        // 从广播通道中获取消息,并加锁
        message := <- broadcast
        mutex.Lock()
        for client := range clients {
            if err := client.WriteMessage(websocket.TextMessage, message); err != nil {
                fmt.Println(err)
                client.Close()
                delete(clients, client)
            }
        }
        mutex.Unlock()
    }
}

In der Funktion handleConnections wird der Client nach erfolgreicher Verbindung zur Karte hinzugefügt und gesperrt. Sperren Sie in der Funktion handleMessages vor der Verarbeitung neuer Nachrichten, um die Datensicherheit zu gewährleisten.

Zusammenfassend lässt sich sagen, dass die Verwendung der Go-Sprache zur Implementierung der Multithread-Websocket-Kommunikation die Effizienz und Stabilität der Websocket-Kommunikation verbessern und Broadcast-Nachrichten problemlos implementieren kann. In der Praxis können je nach Bedarf komplexere Funktionen implementiert werden.

Das obige ist der detaillierte Inhalt vonSo implementieren Sie Multithread-Websocket-Kommunikation mithilfe der Go-Sprache. 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