Heim  >  Artikel  >  Backend-Entwicklung  >  Wie richte ich den Go WebSocket-Server ein?

Wie richte ich den Go WebSocket-Server ein?

WBOY
WBOYOriginal
2024-05-31 22:47:59798Durchsuche

So erstellen Sie einen Go WebSocket-Server: Installieren Sie die Gorilla/Websocket-Bibliothek. Erstellen Sie einen HTTP-Server zur Verarbeitung von WebSocket-Handshake-Anfragen. Aktualisieren Sie HTTP-Anfragen auf WebSocket-Verbindungen. Verarbeiten Sie WebSocket-Nachrichten auf der Serverseite, einschließlich Senden und Empfangen von Daten. Der Server kann erweitert werden, um es Clients zu ermöglichen, bestimmte Kanäle zu abonnieren und Nachrichten nur von diesen Kanälen zu empfangen.

Go WebSocket 服务器如何搭建?

Erstellen Sie einen Go WebSocket-Server

WebSocket ist ein Vollduplex-Kommunikationsprotokoll, das es Clients und Servern ermöglicht, Daten in beide Richtungen über eine einzige TCP-Verbindung zu übertragen. Die Go-Sprache bietet leistungsstarke Unterstützung für den Aufbau von WebSocket-Servern. In diesem Artikel wird anhand praktischer Beispiele erläutert, wie Sie mit Go einen WebSocket-Server erstellen.

Erste Schritte

Zunächst benötigen Sie eine Go-Entwicklungsumgebung, die den Go-Compiler und einen Code-Editor enthält. Sie müssen außerdem die Bibliothek gorilla/websocket installieren, die eine WebSocket-Implementierung in Go bereitstellt. gorilla/websocket 库,它提供了 Go 语言的 WebSocket 实现。

go get -u github.com/gorilla/websocket

创建服务器

WebSocket 服务器本质上是一个传统的 HTTP 服务器,但它处理的是 WebSocket 握手请求。下面是如何在 Go 中创建 WebSocket 服务器:

package main

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

    "github.com/gorilla/websocket"
)

func main() {
    // 升级 HTTP 请求到 WebSocket 连接
    upgrader := websocket.Upgrader{
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
    }

    http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
        conn, err := upgrader.Upgrade(w, r, nil)
        if err != nil {
            log.Fatal(err)
        }

        // websocket.Conn 是一个双向的连接
        for {
            // 从客户端接收消息
            messageType, p, err := conn.ReadMessage()
            if err != nil {
                log.Fatal(err)
            }

            // 将消息返回客户端
            if err := conn.WriteMessage(messageType, p); err != nil {
                log.Fatal(err)
            }
        }
    })

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

实战案例

现在,我们来扩展这个服务器,允许客户端订阅特定的频道并仅接收来自这些频道的消息。

package main

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

    "github.com/gorilla/websocket"
)

type channel struct {
    sync.Mutex
    clients map[*websocket.Conn]bool
}

var channels = struct {
    sync.RWMutex
    m map[string]*channel
}{m: make(map[string]*channel)}

func NewChannel(name string) *channel {
    channels.Lock()
    defer channels.Unlock()

    if _, ok := channels.m[name]; !ok {
        channels.m[name] = &channel{clients: make(map[*websocket.Conn]bool)}
    }
    return channels.m[name]
}

func main() {
    upgrader := websocket.Upgrader{
        ReadBufferSize:  1024,
        WriteBufferSize: 1024,
    }

    http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
        conn, err := upgrader.Upgrade(w, r, nil)
        if err != nil {
            log.Fatal(err)
        }

        // 订阅和取消订阅频道
        go func() {
            for {
                // 从客户端接收消息
                messageType, p, err := conn.ReadMessage()
                if err != nil {
                    log.Fatal(err)
                }

                // 如果消息是一种订阅请求,则将连接添加到相应频道
                if messageType == websocket.TextMessage && string(p)[:4] == "join" {
                    channelName := string(p)[5:]
                    channel := NewChannel(channelName)

                    // 锁定频道的客户端列表
                    channel.Lock()
                    channel.clients[conn] = true
                    // 解锁频道的客户端列表
                    channel.Unlock()
                }

                // 如果消息是一种取消订阅请求,则将连接从相应频道中移除
                if messageType == websocket.TextMessage && string(p)[:7] == "leave" {
                    channelName := string(p)[8:]
                    channel := NewChannel(channelName)

                    channel.Lock()
                    delete(channel.clients, conn)
                    channel.Unlock()
                }
            }
        }()

        // 广播消息到客户端
        go func() {
            for {
                // 分别广播来自每个频道的消息
                channels.RLock()
                for _, channel := range channels.m {
                    channel.RLock()
                    for client := range channel.clients {
                        if err := client.WriteMessage(websocket.TextMessage, "hello"); err != nil {
                            // 如果写入失败,则从频道中移除连接
                            channel.Lock()
                            delete(channel.clients, client)
                            channel.Unlock()
                        }
                    }
                    channel.RUnlock()
                }
                channels.RUnlock()
            }
        }()
    })

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

现在,你可以启动服务器并使用 WebSocket 客户端连接到 /wsrrreee

Server erstellen🎜🎜Ein WebSocket-Server ist im Wesentlichen ein herkömmlicher HTTP-Server, verarbeitet jedoch WebSocket-Handshake-Anfragen. So erstellen Sie einen WebSocket-Server in Go: 🎜rrreee🎜 Praktisches Beispiel 🎜🎜 Nun erweitern wir diesen Server, damit Clients bestimmte Kanäle abonnieren und Nachrichten nur von diesen Kanälen empfangen können. 🎜rrreee🎜Jetzt können Sie den Server starten und einen WebSocket-Client verwenden, um eine Verbindung zum Endpunkt /ws herzustellen, den Kanal zu abonnieren und Nachrichten vom Kanal zu empfangen. 🎜

Das obige ist der detaillierte Inhalt vonWie richte ich den Go WebSocket-Server ein?. 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