Go言語でWebSocketを用いたチャットアプリケーションを動かす

WebSocketがどういうものなのか気になっていたので、今回はWebSocketの簡単な説明と、Go言語で実装されたgorilla/websocket
パッケージを用いてサンプルのチャットアプリケーションを動かしてみようと思います。
なお今回の内容は、WebSocketがどういったものかをイメージしてもらうための内容で細かな実装方法などに関しては触れません。
WebSocketとは
WebSocketとは、コンピューターネットワークの通信プロトコルの一つで、双方向通信を低コストで実現するための技術です。
といっても、イメージしにくかったり、何がいいのかわかりにくかったりするかと思います。
ネットワークの通信プロトコルとは、ネットワークで通信を行う際の取り決めで、HTTP、SMTP、TCP/IPなどが有名で、特にHTTPはWebアプリケーションを開発する上でかなり馴染みがあるものかと思います。
HTTP通信は、クライアント側からサーバーにリクエストを送り、サーバーからのレスポンスを受け取るという通信です。これによってHTMLを受け取って表示したり、AjaxでJSONなどを受け取り画面を動的に変えることができます。このプロトコルによってWebが発展してきたとも言えるようなプロトコルです。
ただHTTP通信にも苦手なことがあります。
それは、サーバーからクライアントにデータをプッシュ配信するということです。
例えば、複数でチャットを行うアプリケーションなどの場合、一人がメッセージを送った後、すぐに他の人にそのメッセージを表示させるといった場合、Ajaxで時間ごとにサーバーに更新がないかというリクエストを送り続ける(ポーリング)必要があります。
この時間の間隔が長ければ通信の頻度も量も少なく済むためサーバーの負担は少なく済みますが、チャットアプリとして使いにくいものになってしまいますし、間隔を短くするとサーバーとクライアントのやり取りが頻繁に発生することによって、サーバーの負担が大きくなってしまいます。
こういったリアルタイムの双方向通信の難しさを解決するために開発されたプロトコルがWebSocketです。
通信では送り手と受け手のコネクションを確立した後、プロトコルの取り決めによって情報の転送を行うハンドシェイクということを行いますが、HTTPでは毎回コネクションの接続をし直すということを無駄が生じますが、WebSocketでは、コネクションを確立した後は、通信を全てそのコネクション上でプロトコルに則って通信を行うことによって通信のロスを減らしたり、サーバからでもクライアントからでも好きなタイミングでデータのやり取りを行うことができます。
実際にWebSocket通信を行うまでの流れは、クライアントからサーバーにプロトコルのアップグレードを行いたいというリクエストを送り、WebSocketに切り替えプロトコルをアップグレードすることによって、WebSocket通信のコネクションを確立します。
WebSocketの詳細な仕様については、RFC 6455(日本語訳)にまとめられています。
実際にWebSocketを使ったアプリケーションを動かす
今回は、Go言語でWebSocket通信を実装されたパッケージのgorilla/websocketのサンプルアプリケーションを動かしてみます。
実行環境
$ go version
go version go1.10.4 darwin/amd64
準備
チャットのサンプルアプリケーションのコードは以下のリンクにあります。
README.md
に沿って、アプリケーションを実行します。
$ go get github.com/gorilla/websocket
$ cd `go list -f '{{.Dir}}' github.com/gorilla/websocket/examples/chat`
$ go run *.go
ブラウザでlocalhost:8080
に接続すると、チャット欄が表示されます。
実行画面
このように、メッセージの送信がリアルタイムで反映されているのがわかるかと思います。
まとめ
今回は実装の詳細などは深くまで見ることはできませんでした。
WebSocketは、今回のチャットのようなものやSNSなどのリアルタイム性が重要になってくるアプリでは、今後導入が増えて一般的になっていくかと思います。
WebSocketならではのセキュリティに気をつける必要があることがあったりするので、導入する際には気をつける必要がありますが、興味を持った方は実際にWebSocketを使って何かを実装してみると面白いかもしれません。