socket.ioの習作解説その弐
<!-- ブラウザ側 --> <script src='/socket.io/socket.io.js'></script> <script src='/javascripts/jquery-2.0.3.min.js'></script>
今回サンプルのHTMLにはサーバ側で動くコードは一切なく、すべてブラウザ上で実行されます。その中でsocket.ioの賢い仕組みとしてはこちら。/socket.io/socket.io.jsを要求してダウンロードします。一緒に並べているjQueryのコードの要求とはちょっと違って、socket.io.jsは下記サーバコードがサービスします。jquery-2.0.3.min.jsは先に作ったexpressでの静的WEBサーバがサービスしてくれています。
//サーバ側 var chatroom = require('socket.io').listen(server).of('/chatroom');
require('socket.io').listen()の引数に、別に作ったhttp.Serverを渡せば通常のHTTPサーバの陰に隠れてWebSocketのサーバが上がります。その後のof()はこのWebSocketに名前空間をつける機能で、まあ普通の神経ならこうするんだろうと。グローバルな名前空間でサービス立ち上げてると、後にサービス仕様の拡張で別サービスを同居させたくなったときに書き直しが発生するし。もちろん上記ではワンライナーで書いちゃってるので、下記のように書き換えないといけないけど。
//サーバ側 var io = require('socket.io').listen(server); var chatroom = io.of('/chatroom'); var viproom = io.of('/viproom');
脱線しましたが、ここまでやるとブラウザへsocket.io.jsがダウンロードされます。このダウンロードしたコードを使って通信始めるところがHTMLのscriptタグ内の以下。
<!-- ブラウザ側 --> $(function() { var chatroom = io.connect('/chatroom'); //(省略) });
jQueryのReadyハンドラで、io.connect()するだけ。引数には名前空間を指定します。ここで世のドキュメントの多くは「http://localhost/chatroom」みたいにホストも書いちゃってるけど、私はそう書いちゃいけないように思うんだよなあ。ブラウザのセキュリティモデル上、スクリプトダウンロード元としか通信しちゃダメだよね。この辺は理由が謎。localhostで動作確認すると問題なく上記の「/chatroom」で動きます。グローバル空間は「/」でよいです。
世のWebSocketの読み物など参考にすると、一発目のhttpでWebSocket接続を要求して双方コンディション整えばつなぎっぱなし、昔の言葉で言えばcometとかいうようなこと、になると。socket.ioはこのへんの接続を整えるところはこれだけのコードに機能集約されて楽チンです。ブラウザ種別の挙動の違いも吸収しているのだとも。素敵です。