WebSocketを触る機会があったのでGo言語で簡単にWebSocketを実装して動作を検証してみました。
WebSocketは、Webアプリケーションでリアルタイム通信を実現するためのプロトコルです。
WebSocketを使用することで、サーバーとクライアント間で双方向通信を行うことができます。
この記事では、Go言語を使用してWebSocketを実装する方法をチャットっぽいものを例にして紹介します。
WebSocketとは
WebSocketは、クライアントとサーバ間でのリアルタイム通信を実現するためのプロトコルです。
WebSocketを使用することで、Webアプリケーションはサーバからのイベントを受け取ったりサーバにデータを送信したりすることができます。
サーバとクライアント間で双方向通信を行うことができるため、リアルタイムでのデータの送受信が可能です。
また、WebSocketは長期間接続を維持することができるためクライアントとサーバ間でのやり取りを継続することができます。
現在ではさまざまなタイプのリアルタイムアプリケーション(例えば、オンラインゲームやチャットアプリケーション)で広く使われています。

WebSocketのクライアント側
必要箇所だけピックアップするのでソースコード全体はこちらから↓
まずはサーバーからメッセージを受け取るところから見ていきます。
window.onload = function () {
    socket = new WebSocket("ws://localhost:3000/ws");
    socket.onopen = function () {
        updateMessage("接続できました");
    };
    socket.onmessage = function (event) {
        // サーバーからメッセージを受け取る
        updateMessage(event.data);
    };
};ページを読み込んだ際にWebSocketサーバーのURLを指定してWebSocketオブジェクトを生成します。
onopenメソッドではWebSocket接続が開始されたときに実行されます。
onmessageメソッドではサーバからのメッセージを受け取るたびに実行され、受け取ったメッセージを表示しています。
updateMessageメソッドはWebページにメッセージを表示するための関数です。
次にサーバーにメッセージを送信します。
function send() {
    let sendMessage = document.getElementById("message");
    let msg = sendMessage.value;
    if (msg == "") {
        return;
    }
    socket.send(msg);
    updateMessage(msg);
    sendMessage.value = "";
}HTMLから送信するメッセージを取得しWebSocketオブジェクトのsendメソッドを使用して、送信するメッセージをWebSocketサーバに送信しています。
WebSocketのサーバー側
今回はgolang.org/x/net/websocketパッケージを使った方法になります。
いろいろ調べているとgorilla/websocketを使った方法もありました。
mainメソッドから見ていきます。
var broadcast = make(chan string)
func main() {
	http.HandleFunc("/", index)
	http.Handle("/ws", websocket.Handler(handleConnection))
	go handleMessages()
	// HTTPサーバーを開始して、ポート3000でリクエストを待ち受け
	err := http.ListenAndServe(":3000", nil)
	if err != nil {
		log.Fatal(err)
	}
}最初にブロードキャストするためのchannel宣言をしておきます。
WebSocketのルーティングを登録し、メッセージを処理するメソッドをゴルーチンで実行します。
次にhandleConnectionを見ていきます。
func handleConnection(ws *websocket.Conn) {
	defer ws.Close()
	// 初回のメッセージを送信
	err := websocket.Message.Send(ws, "こんにちは!")
	if err != nil {
		log.Fatalln(err)
	}
	clients[ws] = true
	for {
		// メッセージを受信する
		msg := ""
		err = websocket.Message.Receive(ws, &msg)
		if err != nil {
			log.Fatalln(err)
		}
		// 受け取ったメッセージをbroadcastチャネルに送る
		broadcast <- msg
	}
}クライアントとWebSocketの接続ができたらwebsocket.Message.Sendメソッドで最初のメッセージをサーバー側から送信します。
ループの中でwebsocket.Message.Receiveメソッドを使用して、WebSocket接続から新しいメッセージを受信しています。
受信したメッセージを最初に宣言しておいたbroadcastチャンネルに送信して、他のクライアントにメッセージをブロードキャストすることができます。
最後にメッセージを処理する中身です。
func handleMessages() {
	for {
		// broadcastチャネルからメッセージを受け取る
		msg := <-broadcast
		// 接続中の全クライアントにメッセージを送る
		for client := range clients {
			// メッセージを返信する
			err := websocket.Message.Send(client, fmt.Sprintf(`%q というメッセージを受け取りました。`, msg))
			if err != nil {
				log.Fatalln(err)
			}
		}
	}
}broadcastチャンネルからメッセージを受信し、WebSocket接続しているクライアントに対してメッセージを送信します。
これでメッセージ送信元のクライアント以外のクライアントにもメッセージが送信されます。
挙動確認
上記コードを元にlocalhost:3000にアクセスするとWebSocketが接続されていることがわかります。

ステータスコードが101でプロトコルを切り替えたと書いていますね。
WebSocketでのチャットの挙動を確認してみます。
クライアントから送ったメッセージがサーバーで受け取って返していることがわかります。
しかし、これだと普通のHTTPでも実現可能です。
別ブラウザを2つ起動して確認してみます。
ブラウザAで送信した内容がサーバーに行き、WebSocket接続しているブラウザBにも同じ内容が送信されていることがわかります。























コメント