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 接続が完全に閉じられるようにすることができます。 <div class="code" style="position:relative; padding:0px; margin:0px;"><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("upgrade error:", err)
return
}
defer conn.Close()
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
for {
_, _, err := conn.ReadMessage()
if err != nil {
log.Println("read error:", err)
return
}
}
}</pre><div class="contentsignin">ログイン後にコピー</div></div>上記のコードでは、エラー チェックは conn.ReadMessage()<p> の呼び出しと併置されています。 WebSocket 接続では、<code>ReadMessage()
が受信メッセージの待機をブロックするため、無限ループを使用して、WebSocket が閉じられているかどうかを定期的にチェックして、Error check-call-error check に入らないようにすることができます。 -
を呼び出す無限ループ。 結論
上記のヒントは、WebSocket 接続が頻繁に切断される問題を解決するのに役立ちます。ハートビート メカニズムを利用し、ping 頻度を減らし、WebSocket のシャットダウンを処理することにより、WebSocket 接続の安定性が大幅に向上し、クライアントとのよりスムーズなリアルタイム通信が保証されます。
以上がGo言語でWebSocket接続が頻繁に切断される問題を解決するヒントの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。