ホームページ  >  記事  >  バックエンド開発  >  Golang で WebSocket 接続を開始および終了する方法

Golang で WebSocket 接続を開始および終了する方法

PHPz
PHPzオリジナル
2023-04-14 09:33:141938ブラウズ

Websocket は、クライアントとサーバー間のリアルタイムの双方向通信を可能にするネットワーク プロトコルです。 HTTPポーリングを使用せずに、効率的なデータ送信と低遅延のインタラクション効果を同時に実現できます。 Golang は、優れた同時実行パフォーマンスと優れたコード品質を備えたオープンソースの高性能プログラミング言語です。 Websocket通信においても、Golangは優れた実装方法を持っています。この記事では、Golang で Websocket 接続を開始および終了する方法を紹介します。

Golang での Websocket の実装

Golang で Websocket を実装するには、次の手順を実行する必要があります:

  1. 対応するパッケージをインポートする

Go 言語で Websocket を実装するには、WebSocket および Http パッケージのサポートが必要です。コードは次のとおりです。

import (
    "net/http"
    
    "github.com/gorilla/websocket"
)

その中でも、github.com/gorilla/websocket は複数のプロトコルをサポートする優れた WebSocket パッケージです。これには、WebSocket 接続を迅速に実装するために使用できる、WebSocket 関連の構造と関数がいくつか含まれています。

  1. WebSocket 接続処理関数の定義

WebSocket 接続を処理する関数では、次のタスクを完了する必要があります:

a. WebSocket アップグレードの定義

HTTP リクエストの場合、WebSocket 接続にアップグレードする必要がある場合、それを処理して、関連するアップグレード リクエストを返す必要があります。コードは次のとおりです。

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

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    // 升级为WebSocket连接
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(err)
        return
    }
    
    // 实现WebSocket通信
    ...
}

このコードでは、Upgrader 構造体を使用します。これは、ゴリラ/WebSocket ライブラリで WebSocket アップグレードを実装する関数です。

Upgrader には、読み取りおよび書き込みバッファ サイズと CheckOrigin 関数が含まれています。 CheckOrigin は、リクエストが正当なソースからのものであるかどうかを確認するために使用されます。このメソッドが false を返した場合、アップグレード要求は拒否されます。この例では有効性をチェックする必要がないため、CheckOrigin は常に true を返します。

Upgrader.Upgrade メソッドを呼び出した後、WebSocket オブジェクト ws を取得します。このオブジェクトで ReadMessage や WriteMessage などのメソッドを呼び出して、後続の WebSocket 通信を完了できます。

b. WebSocket メッセージを読み取る

WebSocket 接続を取得した後、クライアントから送信されたメッセージを継続的に読み取る必要があります。 WebSocket メッセージを読み取るには、ReadMessage メソッドを使用できます。コードは次のとおりです。

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    ...
    
    for {
        // 读取消息
        _, message, err := ws.ReadMessage()
        if err != nil {
            log.Println(err)
            break
        }
        
        // 处理消息
        ...
    }
}

このコードでは、for ループを使用して WebSocket からメッセージを継続的に読み取ります。読み取りが失敗した場合、WebSocket 接続は閉じられており、ループは終了します。

c. WebSocket メッセージの送信

クライアントから送信されたメッセージを処理した後、処理結果をクライアントに送信する必要がある場合があります。 WebSocket メッセージを送信するには、WriteMessage メソッドを使用できます。コードは次のとおりです。

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    ...
    
    for {
        ...
        
        // 发送消息
        err = ws.WriteMessage(websocket.TextMessage, []byte(reply))
        if err != nil {
            log.Println(err)
            break
        }
    }
}

このコードでは、WriteMessage メソッドを通じてクライアントにメッセージを送信します。このメソッドの最初のパラメータはメッセージのタイプで、TextMessage または BinaryMessage として指定できます。2 番目のパラメータは、送信されるデータを含むバイト配列です。

  1. WebSocket サービスの開始

上記の手順を完了すると、WebSocket サービスを開始できます。コードは次のとおりです。

func main() {
    http.HandleFunc("/ws", websocketHandler)
    log.Println("Server started at http://127.0.0.1:8080")
    http.ListenAndServe(":8080", nil)
}

このコードでは、http.HandleFunc 関数を呼び出して、「/ws」パスを WebSocket 処理関数 websocketHandler にマップします。最後に、http.ListenAndServe を呼び出してサービスを開始します。

WebSocket 接続を閉じる

WebSocket を使用した後は、接続を手動で閉じる必要があります。 WebSocket 接続を正常に閉じるには、次の点に注意する必要があります:

a. サーバー側が積極的に閉じる

サーバー側は WebSocket 接続を閉じる必要がある場合、 WebSocket.Close メソッド。コードは次のとおりです。

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    defer ws.Close() // 关闭WebSocket连接
    
    for {
        ...
    }
}

このコードでは、defer ステートメントを使用して、WebSocket 関数の終了時に WebSocket 接続を自動的に閉じます。

b. クライアントは積極的に閉じる

クライアントは、WebSocket 接続を閉じる必要がある場合、サーバーに Close メッセージを送信できます。サーバーは Close メッセージを受信し、メッセージの受信後に WebSocket 接続をアクティブに閉じます。

サーバー側の WebSocket 関数に Close メッセージを処理するブランチを追加できます。コードは次のとおりです。

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    ...
    
    for {
        // 读取消息
        messageType, message, err := ws.ReadMessage()
        if err != nil {
            log.Println(err)
            break
        }
        
        // 处理消息
        switch messageType {
        case websocket.CloseMessage:
            // 收到关闭消息,关闭连接
            return
        case websocket.TextMessage:
            // 收到文本消息,处理消息
            ...
        case websocket.BinaryMessage:
            ...
        }
    }
    
    // 关闭WebSocket连接
    ws.Close()
}

このコードでは、メッセージ タイプが CloseMessage の処理ブランチを追加します。 Close メッセージを受信したら、すぐに WebSocket 関数を終了し、WebSocket 接続を閉じます。

c. 異常終了

WebSocket 接続に異常が発生した場合、時間内に接続を終了する必要があります。たとえば、ネットワークが切断された場合、クライアントとサーバー間の接続がタイムアウトした場合など、WebSocket 接続を閉じる必要があります。

WebSocket 関数で例外をキャッチし、例外がキャッチされたときに WebSocket 接続を閉じることができます。コードは次のとおりです。

func websocketHandler(w http.ResponseWriter, r *http.Request) {
    defer ws.Close() // 当函数退出时关掉WebSocket连接
    
    for {
        _, message, err := ws.ReadMessage()
        if err != nil {
            if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
                log.Printf("error: %v", err)
            }
            break
        }
        
        // 处理消息
        ...
    }
}

このコードでは、WebSocket 関数が戻る前に、defer ステートメントを通じて WebSocket 接続を手動で閉じます。 ReadMessage オペレーションに、例外エラーをキャプチャしてログ出力を実行する機能を追加しました。

概要

Golang では、WebSocket 接続は、ゴリラ/WebSocket ライブラリを通じて実現できます。 WebSocket通信の処理機能にUpgrader構造を利用することで、HTTPプロトコルをWebSocketにアップグレードすることができます。 WebSocket に接続するときは、WebSocket メッセージの読み取りおよび送信操作を実装する必要があります。

WebSocket 接続を正常に終了するには、次の点に注意する必要があります。

  1. サーバーは、操作の完了後に WebSocket 接続を手動で閉じる必要があります。
  2. クライアントが Close メッセージを受信したら、サーバーはすぐに WebSocket 接続を閉じる必要があります。
  3. WebSocket 接続が発生する 例外が発生した場合は、例外をキャッチした後、速やかに接続を閉じる必要があります。

以上がGolang で WebSocket 接続を開始および終了する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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