ホームページ バックエンド開発 Golang Go 言語 Websocket 開発ガイド: メッセージ損失の問題に対処する方法

Go 言語 Websocket 開発ガイド: メッセージ損失の問題に対処する方法

Dec 14, 2023 pm 01:47 PM
言語を移動 websocket メッセージが失われました

Go 言語 Websocket 開発ガイド: メッセージ損失の問題に対処する方法

Go 言語 Websocket 開発ガイド: メッセージ損失の問題を処理する方法

  1. はじめに
    現代のネットワーク アプリケーションでは、リアルタイム メッセージングがますます増えています。重要 重要であればあるほど。 Websocket は双方向通信プロトコルとして、クライアントとサーバーの間に永続的な接続を確立し、リアルタイムのデータ送信を実現します。ただし、ネットワークの不安定性やその他の理由により、メッセージの損失が発生する可能性があります。この記事では、Go 言語を使用して Websocket アプリケーションを開発し、メッセージ損失の問題に対処する方法を紹介します。
  2. Go 言語を使用して Websocket アプリケーションを開発する
    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)
ログイン後にコピー
  1. メッセージ損失問題の処理
    Websocket アプリケーションでは、メッセージが失われることがあります。ネットワーク障害やその他の理由により紛失した場合。この問題を解決するには、いくつかの技術的手段を使用できます。

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上記のコードでは、タイマーを使用して一定の間隔でハートビート メッセージを送信し、ハートビート タイムアウトを設定してハートビート応答を待ちます。一定期間内にハートビート応答が受信されない場合、接続は切断されたとみなされます。

  1. 概要
    この記事では、Go 言語を使用して Websocket アプリケーションを開発し、メッセージ損失の問題に対処する方法を紹介します。メッセージ確認メカニズムとハートビート メカニズムを使用することで、メッセージ損失の問題を効果的に解決できます。もちろん、具体的なビジネスシナリオに応じて、必要に応じてより詳細な処理を実行することもできます。

この記事を学ぶことで、Go 言語での Websocket 開発をすぐに理解し、これらのテクノロジーを実際のプロジェクトに適用することができます。この記事がお役に立てば幸いです!

以上がGo 言語 Websocket 開発ガイド: メッセージ損失の問題に対処する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

GOの浮動小数点番号操作に使用されるライブラリは何ですか? GOの浮動小数点番号操作に使用されるライブラリは何ですか? Apr 02, 2025 pm 02:06 PM

GO言語の浮動小数点数操作に使用されるライブラリは、精度を確保する方法を紹介します...

Go's Crawler Collyのキュースレッドの問題は何ですか? Go's Crawler Collyのキュースレッドの問題は何ですか? Apr 02, 2025 pm 02:09 PM

Go Crawler Collyのキュースレッドの問題は、Go言語でColly Crawler Libraryを使用する問題を調査します。 �...

Goでは、Printlnとstring()関数を備えた文字列を印刷すると、なぜ異なる効果があるのですか? Goでは、Printlnとstring()関数を備えた文字列を印刷すると、なぜ異なる効果があるのですか? Apr 02, 2025 pm 02:03 PM

Go言語での文字列印刷の違い:printlnとstring()関数を使用する効果の違いはGOにあります...

GOのどのライブラリが大企業によって開発されていますか、それとも有名なオープンソースプロジェクトによって提供されていますか? GOのどのライブラリが大企業によって開発されていますか、それとも有名なオープンソースプロジェクトによって提供されていますか? Apr 02, 2025 pm 04:12 PM

大企業または有名なオープンソースプロジェクトによって開発されたGOのどのライブラリが開発されていますか? GOでプログラミングするとき、開発者はしばしばいくつかの一般的なニーズに遭遇します...

Golandのカスタム構造ラベルが有効になっていないという問題を解決する方法は? Golandのカスタム構造ラベルが有効になっていないという問題を解決する方法は? Apr 02, 2025 pm 12:51 PM

GoLandを使用する場合のGolandのカスタム構造タグの問題に関して、Go Language Developmentに使用する場合、いくつかの構成の問題に遭遇することがよくあります。それらの1つは...

GOに効率的なキー値ペアストレージを実装する最良の方法は何ですか? GOに効率的なキー値ペアストレージを実装する最良の方法は何ですか? Apr 02, 2025 pm 01:54 PM

GO言語で効率的なキー価値ペアストレージを実装する正しい方法GO言語でRedisと同様のキー値ペアメモリを開発するときに最高のパフォーマンスを実現する方法...

GoおよびViperライブラリを使用するときにポインターを渡す必要があるのはなぜですか? GoおよびViperライブラリを使用するときにポインターを渡す必要があるのはなぜですか? Apr 02, 2025 pm 04:00 PM

ポインター構文とviperライブラリの使用における問題への取り組みGO言語でプログラミングするとき、特にポインターの構文と使用を理解することが重要です...

GO言語は、大規模なURLアクセスを処理するのに非効率的であり、最適化する方法は? GO言語は、大規模なURLアクセスを処理するのに非効率的であり、最適化する方法は? Apr 02, 2025 am 10:15 AM

GO言語のパフォーマンス最適化戦略大規模なURLアクセスこの記事では、GO言語を使用して大規模なURLアクセスを処理する問題に関するパフォーマンス最適化ソリューションを提案します。 CSVからの既存のプログラム...

See all articles