ホームページ  >  記事  >  バックエンド開発  >  Go言語でWebSocket接続が頻繁に切断される問題を解決するヒント

Go言語でWebSocket接続が頻繁に切断される問題を解決するヒント

王林
王林オリジナル
2023-12-14 13:45:511469ブラウズ

Go言語でWebSocket接続が頻繁に切断される問題を解決するヒント

Web アプリケーションの人気に伴い、最も一般的に使用される通信プロトコルの 1 つである WebSocket は、クライアントとサーバー間のリアルタイム通信によく使用されます。 Go 言語では、gorilla/websocket は、WebSocket を使用するための最も人気のあるサードパーティ ライブラリの 1 つです。ただし、WebSocket を使用すると、頻繁に切断されるという問題が発生します。この問題を解決するためのヒントと、関連する Go コードの例を以下に示します。

1. 接続ハートビート

WebSocket の使用では、ブラウザ/クライアントのネットワーク接続の切断やサーバー側の一時停止アニメーションなど、いくつかの要因により接続が切断される可能性があります。 。これらの問題を解決するには、ハートビート操作を使用して接続を維持できます。ハートビート操作では、具体的には、WebSocket 接続を維持するために ping メッセージを送信し、応答を検出するために goutine を開始します。

以下はサンプル コードです:

package main

import (
    "log"
    "net/http"
    "time"

    "github.com/gorilla/websocket"
)

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

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

func wsHandler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println("upgrade error:", err)
        return
    }
    defer conn.Close()

    heartbeat(conn)
}

func heartbeat(conn *websocket.Conn) {
    ticker := time.NewTicker(10 * time.Second)

    defer ticker.Stop()

    for {
        select {
        case <-ticker.C:
            if err := conn.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
                log.Println("write ping error:", err)
                return
            }
        }
    }
}

上記のコードでは、heartbeat 関数が groutin を開始します。 ##10 秒ごとに ping メッセージを送信します。 ping メッセージが送信されると、select ステートメントは、pong メッセージを受信するまで 500 ミリ秒待機します。 Pong メッセージが受信されない場合、接続が切断されるか、エラーが返されます。この例では、ハートビートを使用して WebSocket 接続を維持する方法を示します。 2. クライアントの ping リクエストの頻度を減らす

場合によっては、頻繁に ping リクエストを送信すると、WebSocket 接続が中断される可能性があります。たとえば、WebSocket を企業ネットワーク プロキシで使用すると、プロキシが継続的な ping 要求をブロックする可能性があります。

この状況を回避するには、ping メッセージの頻度を減らすことができます。たとえば、以下のスニペットでは、Heartbeat は 10 秒間隔で ping リクエストを送信します。 ping 頻度を制御し、適切に調整すると、WebSocket 接続の安定性が向上します。

func heartbeat(conn *websocket.Conn) {
    ticker := time.NewTicker(10 * time.Second)

    defer ticker.Stop()

    for {
        select {
        case <-ticker.C:
            if err := conn.WriteMessage(websocket.PingMessage, []byte{}); err != nil {
                log.Println("write ping error:", err)
                return
            }
        }
    }
}

3. WebSocket のクローズを処理する

切断を避けるために、WebSocket 接続がクローズされているかどうかを定期的に確認します。 WebSocket 接続を閉じる

defer

関数を追加して、関数が終了する前に WebSocket 接続が完全に閉じられるようにすることができます。 <pre class='brush:go;toolbar:false;'>func wsHandler(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println(&quot;upgrade error:&quot;, err) return } defer conn.Close() ticker := time.NewTicker(10 * time.Second) defer ticker.Stop() for { _, _, err := conn.ReadMessage() if err != nil { log.Println(&quot;read error:&quot;, err) return } } }</pre>上記のコードでは、エラー チェックは

conn.ReadMessage()

の呼び出しと併置されています。 WebSocket 接続では、ReadMessage() が受信メッセージの待機をブロックするため、無限ループを使用して、WebSocket が閉じられているかどうかを定期的にチェックして、Error check-call-error check に入らないようにすることができます。 - を呼び出す無限ループ。 結論

上記のヒントは、WebSocket 接続が頻繁に切断される問題を解決するのに役立ちます。ハートビート メカニズムを利用し、ping 頻度を減らし、WebSocket のシャットダウンを処理することにより、WebSocket 接続の安定性が大幅に向上し、クライアントとのよりスムーズなリアルタイム通信が保証されます。

以上がGo言語でWebSocket接続が頻繁に切断される問題を解決するヒントの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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