ホームページ  >  記事  >  バックエンド開発  >  Go WebSocket は同時接続をどのように処理しますか?

Go WebSocket は同時接続をどのように処理しますか?

PHPz
PHPzオリジナル
2024-06-04 09:02:00976ブラウズ

同時接続を処理するための Go WebSocket のアプローチ: 接続ごとに Goroutine を使用します。チャネルを通じて通信を接続します。 [gowebsocket](https://github.com/gobwas/ws)、[gorilla/websocket](https://github.com/gorilla/websocket) などのサードパーティ ライブラリを使用して処理を簡素化します。

Go WebSocket 如何处理并发连接?

Go WebSocket が同時接続を処理する方法

WebSocket は、クライアントとサーバー間のリアルタイムの双方向通信を可能にする全二重通信プロトコルです。 Go で WebSocket の同時接続を処理する一般的な方法は次のとおりです:

1. Goroutine

簡単な解決策は、接続ごとに Goroutine を使用することです。 Goroutine は、並列実行できる Go の軽量スレッドです。新しい WebSocket 接続が確立されると、それを処理するための新しい Goroutine を作成できます:

package main

import (
    "fmt"
    "net/http"
    "os"

    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{}

func main() {
    // WebSocket 服务器端口号
    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        // 对请求进行 WebSocket 升级
        conn, err := upgrader.Upgrade(w, r, nil)
        if err != nil {
            fmt.Println(err)
            return
        }

        // 创建一个 Goroutine 处理连接
        go handleConnection(conn)
    })

    http.ListenAndServe(":"+port, nil)
}

// handleConnection 处理一个 WebSocket 连接
func handleConnection(conn *websocket.Conn) {
    for {
        msgType, msg, err := conn.ReadMessage()
        if err != nil {
            fmt.Println(err)
            break
        }

        if msgType == websocket.TextMessage {
            // 处理文本消息
            fmt.Println("Received text message:", string(msg))
            if err := conn.WriteMessage(msgType, msg); err != nil {
                fmt.Println(err)
            }
        } else {
            // 处理其他类型的消息
        }
    }

    conn.Close()
}

2. チャネル

Channel は Go の通信に使用される同時チャネルです。チャネルを介して複数の接続を処理できます:

package main

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

    "github.com/gorilla/websocket"
)

var (
    upgrader = websocket.Upgrader{}
    connections = make(chan *websocket.Conn, 100)
    wg sync.WaitGroup
)

func main() {
    // WebSocket 服务器端口号
    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        // 对请求进行 WebSocket 升级
        conn, err := upgrader.Upgrade(w, r, nil)
        if err != nil {
            fmt.Println(err)
            return
        }

        // 将连接添加到 Channel
        connections <- conn
    })

    // 启动一个 Goroutine 处理 Channel 中的连接
    go handleConnections()

    http.ListenAndServe(":"+port, nil)
}

// handleConnections 处理 Channel 中的 WebSocket 连接
func handleConnections() {
    for {
        conn := <-connections

        wg.Add(1)
        go func() {
            defer wg.Done()
            for {
                msgType, msg, err := conn.ReadMessage()
                if err != nil {
                    fmt.Println(err)
                    break
                }

                if msgType == websocket.TextMessage {
                    // 处理文本消息
                    fmt.Println("Received text message:", string(msg))

                    // 向所有连接的客户端广播消息
                    for c := range connections {
                        if c != conn {
                            if err := c.WriteMessage(msgType, msg); err != nil {
                                fmt.Println(err)
                            }
                        }
                    }
                } else {
                    // 处理其他类型的消息
                }
            }

            conn.Close()
        }()
    }
}

パイプを介して接続を渡すと、すべてのゴルーチン間で接続を共有でき、スレッドを作成しすぎることによるオーバーヘッドを回避できます。

3. サードパーティ ライブラリ

次のような、WebSocket の同時処理を簡素化できるサードパーティ ライブラリが多数あります。 [ゴリラ/ウェブソケット](https://github.com/gorilla/websocket)

    [fasthttp/websocket](https://github.com/valyala/fasthttp/blob/master/websocket/websocket.go)
  • これらのライブラリは、同時接続を処理し、WebSocket の使用を簡素化するための高レベルの API を提供します。

以上がGo WebSocket は同時接続をどのように処理しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。