Go 言語 Websocket 開発ガイド: メッセージ損失の問題を処理する方法
まず、net/http
および github.com/gorilla/websocket
パッケージをインポートする必要があります。
import ( "net/http" "github.com/gorilla/websocket" )
次に、WebSocket プロセッサを作成します。
func handleWebsocket(w http.ResponseWriter, r *http.Request) { // 允许跨域连接 upgrader := websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, } // 升级HTTP连接为Websocket连接 conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println("Websocket upgrade failed: ", err) return } // 处理消息 for { messageType, message, err := conn.ReadMessage() if err != nil { log.Println("Read error: ", err) break } // 处理消息逻辑 handleMessage(message) // 回复消息 err = conn.WriteMessage(messageType, message) if err != nil { log.Println("Write error: ", err) break } } // 关闭连接 conn.Close() }
上記のコードでは、まず Upgrader
構造を通じて HTTP 接続を WebSocket 接続にアップグレードします。その後、例外が発生するか接続が閉じられるまで、ループしてメッセージを読み取り、処理し、応答します。
最後に、HTTP サーバーを作成し、指定されたパスに Websocket プロセッサを登録します。
http.HandleFunc("/websocket", handleWebsocket) http.ListenAndServe(":8000", nil)
3.1 メッセージ確認メカニズム
一意の識別子 (インクリメントされたシーケンス番号など) をメッセージに追加できます。受信者はメッセージを受信すると、送信者に確認メッセージを送信します。送信者は、一定時間内に確認メッセージを受信しない場合、メッセージを再送する必要があります。
メッセージ確認メカニズムを処理するための構造体を定義できます:
type Message struct { ID int Content string AckChan chan int } type MessageHandler struct { messages map[int]Message } func (handler *MessageHandler) handleMessage(message Message) { // 处理消息逻辑 // ... // 发送确认消息 message.AckChan <- message.ID }
handleWebsocket
関数では、次の方法でメッセージを処理できます:
messageHandler := MessageHandler{ messages: make(map[int]Message), } for { messageType, message, err := conn.ReadMessage() if err != nil { log.Println("Read error: ", err) break } // 创建消息对象 ackChan := make(chan int) msg := Message{ ID: len(messageHandler.messages) + 1, Content: string(message), AckChan: ackChan, } // 处理消息 messageHandler.handleMessage(msg) // 等待确认消息 select { case <-ackChan: // 收到确认消息 case <-time.After(time.Second): // 消息发送超时,重新发送消息 conn.WriteMessage(messageType, message) } // 回复消息 err = conn.WriteMessage(messageType, message) if err != nil { log.Println("Write error: ", err) break } }
MessageHandler
では、マップを使用して、送信されたがまだ確認を受け取っていないメッセージを保存します。確認メッセージを受信すると、マップからメッセージが削除されます。
メッセージ処理ロジックが完了すると、確認メッセージが送信者に送信され、送信者は渡された AckChan
チャネルを通じて確認メッセージを受信します。一定時間内に確認メッセージを受信できない場合は、メッセージを再送信します。
3.2 ハートビート メカニズム
メッセージ確認メカニズムの使用に加えて、ハートビート メカニズムを使用して接続が正常かどうかを検出することもできます。
クライアントにハートビート メッセージを定期的に送信できます。一定時間以内に応答が受信されない場合、接続は切断されたものとみなされます。
ハートビート構造を定義できます:
type Heartbeat struct { PingMsg []byte PongMsg []byte Interval time.Duration } func (h *Heartbeat) Start(conn *websocket.Conn) { ticker := time.NewTicker(h.Interval) defer ticker.Stop() for range ticker.C { // 发送心跳消息 err := conn.WriteMessage(websocket.PingMessage, h.PingMsg) if err != nil { log.Println("Heartbeat error: ", err) break } // 设置心跳超时时间 conn.SetReadDeadline(time.Now().Add(h.Interval)) // 等待心跳回复 _, _, err = conn.ReadMessage() if err != nil { log.Println("Heartbeat error: ", err) break } } }
handleWebsocket
関数では、次の方法でハートビートをオンにできます:
heartbeat := Heartbeat{ PingMsg: []byte("ping"), PongMsg: []byte("pong"), Interval: time.Second * 10, } go heartbeat.Start(conn)
In上記のコードでは、タイマーを使用して一定の間隔でハートビート メッセージを送信し、ハートビート タイムアウトを設定してハートビート応答を待ちます。一定期間内にハートビート応答が受信されない場合、接続は切断されたとみなされます。
この記事を学ぶことで、Go 言語での Websocket 開発をすぐに理解し、これらのテクノロジーを実際のプロジェクトに適用することができます。この記事がお役に立てば幸いです!
以上がGo 言語 Websocket 開発ガイド: メッセージ損失の問題に対処する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。