近年、リアルタイム通信が基本的なニーズになっています。 WebSocket はリアルタイム通信のリーダーであり、クライアントとサーバー間のリアルタイム通信をより迅速かつ効果的に実現できます。 Go 言語も近年人気の言語であり、リアルタイム通信で広く使用されています。 Go言語の利点とマルチスレッド処理の特性を活かして、Websocketの通信機能をより効率的かつ安定的に実現できます。
この記事では Go 言語に焦点を当て、いくつかの重要な関数の実装を含む、Go 言語を使用してマルチスレッド Websocket 通信を実装する方法を紹介し、詳細なコード例を示します。
Go 言語を使用して Websocket 通信を実装する前に、Websocket 通信の基本的な知識を理解する必要があります。 Websocket は、HTTP と同様、TCP に基づくネットワーク プロトコルです。ただし、違いは、これが要求および応答モードではなく、クライアントとサーバー間の継続的な接続であり、両者間のリアルタイム通信が可能であることです。
Go 言語で Websocket 通信を実装する最初のステップは、「net/http」パッケージと「github.com/gorilla/websocket」パッケージをインポートすることです。このうち「net/http」はHTTPサーバーの作成に使用され、「github.com/gorilla/websocket」はWebsocket用のサードパーティパッケージです。このパッケージが利用できない場合は、「go get」コマンドを使用してインストールできます。
import ( "fmt" "net/http" "github.com/gorilla/websocket" )
Go 言語の「http.HandleFunc()」メソッドを使用して、以下に示すように Websocket 接続を確立します。
func main() { http.HandleFunc("/", handleConnections) http.ListenAndServe(":4000", nil) }
上記のコードでは、次のコードを使用します。 " http.HandleFunc()" メソッドは、Websocket 接続の確立を担当する "handleConnections" という名前のハンドラー関数を作成します。ご覧のとおり、Websocket 接続を確立するためのリクエスト パスはルート ディレクトリである「/」です。
Websocket 接続を確立した後、プロトコルのアップグレード、読み取りおよび書き込みキャッシュ サイズ、ハートビート タイムアウトなど、接続リクエストのいくつかの基本パラメータを設定する必要があります。
var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, CheckOrigin: func(r *http.Request) bool { return true }, }
上記のコードは「websocket.Upgrader」を使用して構成されており、「ReadBufferSize」と「WriteBufferSize」は読み取りおよび書き込みバッファ領域のサイズを指定し、「CheckOrigin」は「true」に設定されています。すべてのソース アクセス要求を示します。特定のソースが必要な場合は、特定の要件に従って設定できます。
Websocket 接続リクエストが処理された後、プロトコルのアップグレードのために標準の Websocket プロトコル ハンドシェイクに従う必要があります。 Go 言語では、プロトコル アップグレードでは、Upgrader を使用してプロトコル ハンドシェイクを実行し、接続ハンドル (conn) を返します。接続ハンドルは、Websocket 接続のライフ サイクル中にメッセージを送受信するために使用できます。
func handleConnections(w http.ResponseWriter, r *http.Request) { // 通过Upgrader进行协议升级 ws, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println(err) } // 若协议升级成功,则跳转到另一个处理函数处理消息 go handleMessages(ws) }
handleConnections 関数では、プロトコルは最初に Upgrader を通じてアップグレードされます。アップグレードが成功したら、「go handleMessages(ws)」を呼び出して goroutine を起動し、Websocket メッセージの処理を開始します。
次のステップは、Websocket メッセージ部分を処理することです。 Go 言語では、無限ループを使用して Websocket メッセージの到着を監視し、それに応じて各メッセージを処理できます。
func handleMessages(ws *websocket.Conn) { for { messageType, p, err := ws.ReadMessage() if err != nil { fmt.Println(err) return } // 根据消息类型进行处理 switch messageType { case websocket.TextMessage: // 处理text类型消息 fmt.Println(string(p)) case websocket.BinaryMessage: // 处理binary类型消息 fmt.Println(p) } } }
handleMessages 関数では、まず「ws.ReadMessage()」メソッドを使用して Websocket メッセージを読み取り、メッセージ タイプに従って処理します。
最後の部分は、Websocket メッセージの送信部分です。 Go 言語では、Websocket 接続ハンドル「ws」を使用してクライアントにデータを送信できます。
func sendMessage(ws *websocket.Conn, messageType int, message []byte) error { if err := ws.WriteMessage(messageType, message); err != nil { return err } return nil }
sendMessage 関数では、まず「ws.WriteMessage()」メソッドを通じてメッセージをクライアントに送信します。
Websocket 通信の効率を向上させるために、Websocket メッセージの処理にマルチスレッドを使用する必要があります。 Go言語ではゴルーチンを使用して同時処理を実装できます。
Go 言語では、ゴルーチンの開始は非常に簡単で、関数の前に「go」を追加するだけです。
go handleMessages(ws)
実際の開発では、Websocket は通常、ブロードキャスト メッセージを実装する必要があります。つまり、接続されているすべてのクライアントにメッセージを送信します。 Go 言語では、マップを使用して接続されているすべてのクライアントを保存し、各クライアントをトラバースしてメッセージを順番に送信できます。
var clients = make(map[*websocket.Conn]bool) // 所有连接的客户端 var broadcast = make(chan []byte) // 广播通道 func main() { http.HandleFunc("/", handleConnections) go handleMessages() http.ListenAndServe(":4000", nil) } func handleConnections(w http.ResponseWriter, r *http.Request) { // 通过Upgrader进行协议升级 ws, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println(err) } // 若协议升级成功,则将客户端存入map clients[ws] = true } func handleMessages() { for { // 从广播通道中获取消息 message := <- broadcast // 对所有连接的客户端发送消息 for client := range clients { if err := client.WriteMessage(websocket.TextMessage, message); err != nil { fmt.Println(err) delete(clients, client) return } } } }
上記のコードでは、ブロードキャスト メッセージを処理するためにブロードキャスト チャネル (ブロードキャスト) が実装されています。同時に、接続されているすべてのクライアントを保存するためのマップ (クライアント) が作成されます。 handleConnections 関数では、新しいクライアントが接続すると、それがクライアントに保存されます。 handleMessages 関数では、ブロードキャスト チャネルがそこから新しいメッセージを取得し、接続されているすべてのクライアントに送信します。
Websocket メッセージを複数のスレッドで処理する際には、データの同時実行性の安全性を確保する必要があります。 Go 言語では、同時実行性のセキュリティ制御にロックを使用できます。この記事のサンプル コードでは、「sync.RWMutex」を使用して読み取り/書き込みロックを実装し、同時実行の安全性を確保しています。
var mutex = &sync.RWMutex{} func handleConnections(w http.ResponseWriter, r *http.Request) { // 通过Upgrader进行协议升级 ws, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println(err) } // 若协议升级成功,则将客户端存入map,并进行锁定 mutex.Lock() clients[ws] = true mutex.Unlock() } func handleMessages() { for { // 从广播通道中获取消息,并加锁 message := <- broadcast mutex.Lock() for client := range clients { if err := client.WriteMessage(websocket.TextMessage, message); err != nil { fmt.Println(err) client.Close() delete(clients, client) } } mutex.Unlock() } }
handleConnections 関数では、接続が成功すると、クライアントがマップに追加され、ロックされます。 handleMessages 関数では、データのセキュリティを確保するために、新しいメッセージを処理する前にロックします。
要約すると、Go 言語を使用してマルチスレッド Websocket 通信を実装すると、Websocket 通信の効率と安定性が向上し、ブロードキャスト メッセージを簡単に実装できます。実際には、特定のニーズに応じて、より複雑な機能を実装できます。
以上がGo言語を使用したマルチスレッドWebsocket通信の実装方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。