リアルタイム通信といえばwebsocketですが、このwebsocketを簡単に扱えるようにしたものとしてNode.jsのsocket.ioが使われることが多いと思います。今回はこのsocket.ioの通信プロトコルについて説明したいと思います。
詳細なプロトコルの必要性
なぜ、socket.ioのプロトコルについて書くかと言うと
- socket.ioのプロトコルをまとめているはずのsocket.io-protocolに具体的な説明がない
- 公式ドキュメントに詳細な説明がない
- ネット上に情報が少ない
- socket.ioサーバーに対してJMeterで負荷試験するときにプロトコルを知らないとデータの送受信ができない
理由を上げると切りがないですが、最後にあげた理由が一番ですね。
実際、使用するだけならサンプルコードを参考にすれば何の問題もなく簡単に扱うことができます。
だからこそプロトコルについての詳細な情報が必要とされていないのだと思います。JMeterを使用した負荷試験の記事はまた別で書きたいと思います。
プロトコルの種類
まずはじめに、socket.ioは2つのプロトコルで動作しています。それがsocket.io-protocolとengine.io-protocolです。
ここでは2つの役割については説明しませんが、socket.ioはクライアントから受け取ったデータをsocket.ioプロトコルとengine.ioプロトコルに従って処理を行なっています。
Socket.IOプロトコルについて
ここからが本題になります。例えば下記データの場合、先頭の4はengine.ioプロトコルで、それ以降はsocket.ioプロトコルになります。
4はengine.ioプロトコルでmessage packet typeとなり、2はsocket.ioプロトコルでEVENT typeとなります。/chatはnamespaceで[ ]で挟まれた部分がsocket.ioで処理されるデータになります。
このデータの場合、socket.ioでは”join”イベントが発火され{room:1}のデータが渡されます。namespaceは/のときに限って省略することが可能です。
これがsocket.ioのプロトコルの全てと言っても過言ではありません。この法則させ抑えて置けば他のデータのやり取りも容易に理解できるようになります。
42/chat,[“join”,”{room:1}”]
websocket接続時のデータ
次はsocket.io接続時に実際に送られてくるデータを見ていきたいと思います。今回はUpgradeなしのいきなりwebsocketで繋ぎに行く場合のデータを紹介します。
まずこれはwebsocket接続時に一番最初にサーバーから送られてくるデータです。先頭の0はengine.ioプロトコルでopen packet typeなので接続完了を表します。
ここではsocket.ioプロトコルの0: CONNECT typeは省略されます。socket.ioのCONNECT typeはnamespaceに対しての接続だからかもしれません。
0{“sid”:”co4sBxs6vQ8m4us5AAAA”,”upgrades”:[],”pingInterval”:25000,”pingTimeout”:60000}
websocketのコネクションが確立すると次に下記データがサーバーから送られてきます。これはmessage packet typeとCONNECT typeの組み合わせでnamespace ’/’に接続したことを表します。40は40/と同じ意味になります。
40
まとめ
ここまでくればあとは上記のプロトコルに従えば自由にデータのやり取りをsocket.io上で行うことができます。
どうでしたでしょうか?プロトコルを理解すればすごくシンプルだということが分かったかと思います。もし、説明に間違いがあれば教えていただければと思います。
下記個人ブログにSocket.IOやNode.jsについて他にも色々書いているのでぜひ読んでいただきたいです。
よろしくお願いします。