クロコめも2。

ただのめもー

実践Node.jsプログラミングのマルチルームチャットアプリの構築を写経した時のメモ

世界にはまだまだ知らないことだらけ。Node.jsのサーバサイドについても把握せねば。  

環境

  • node v4.2.3
  • mime 1.3.4 (本では1.2.7)
  • socket.io 1.3.7 (本では0.9.6)

単純に動かなかった2点

1点目 chat_server.js l50~l60あたり

//var usersInRoom = io.sockets.clients(room);
// ↑だとclientsなんぞ知らん。というエラーが起きる
var usersInRoom = findClientsSocket(room);

// 以下のメソッドを別途追加
function findClientsSocket(roomId, namespace) {
    var res = []
        , ns = io.of(namespace ||"/");    // the default namespace is "/"

    if (ns) {
        for (var id in ns.connected) {
            if(roomId) {
                var index = ns.connected[id].rooms.indexOf(roomId) ;
                if(index !== -1) {
                    res.push(ns.connected[id]);
                }
            } else {
                res.push(ns.connected[id]);
            }
        }
    }
    return res;
}

2点目 chat_server.js l20~l30あたり

//socket.emit('rooms', io.sockets.manager.rooms);
// ↑だと「TypeError: Cannot read property 'rooms' of undefined」というエラーが起きる
socket.emit('rooms', io.sockets.rooms);

なぜ動かなかったか?

APIが変わったから。
どうやらsocket.ioの1.0になったときにいろいろ変わったらしいですね

ふぅ。

Server側復習

server.js => ほぼstaticなwebサーバに関する記述
chat_server => socket.ioに関するところだけ抜き出して意味を調べてみる

io = socketio.listen(server)

API docsより

 Server#listen
 Synonym of Server#attach.

 Server#attach(srv:http#Server, opts:Object):Server
 Attaches the Server to an engine.io instance on srv with the
 supplied opts (optionally).

engine.ioとはなんぞや?

https://github.com/socketio/engine.io

socket.io用のトランスポート層で双方向通信するための実装ということか?
これをhttpサーバにアタッチすることでリクエストをインターセプトする

io.set('log level', 1);

意図がわからない。log levelを1にするということはログを多くすることなのか?少なくすることなのか?ログを無くしたいのか?
そしてversion1.0以降はなにやら変わっているらしい。このログレベルの設定自体が不要なのか?

http://socket.io/docs/logging-and-debugging/
↓で何やら説明があった。
http://socket.io/docs/migrating-from-0-9/

Options like log-level are gone. ごーん

socket.emit('eventName', obj);

対象のsocketに対してイベントを発火させる。
渡したいものはobjに詰めておく

socket.join(room)

API docsより

Socket#join(name:String[, fn:Function]):Socket
Adds the socket to the room, and fires optionally a callback fn
with err signature (if any).

The socket is automatically a member of a room identified with its
session id (see Socket#id).

The mechanics of joining rooms are handled by the Adapter
that has been configured (see Server#adapter above), defaulting to
socket.io-adapter.

roomに追加してoptionのコールバックを発火。
roomとはなにものか?

デフォルトではセッションID名のroomに自動的に入れられているってことか

socket.leave

joinの反対で良い模様

socket.broadcast.to(room).emit('message', {...})

ブロードキャスト。

そして↓のように書いても動いた。
socket.to(room).emit('message', {...}
違いはなんだろう?

socket.on('イベント名', function(パラメータ){ハンドリング処理});

見ての通りのイベントハンドリング処理の模様

io.of(...)

カスタムのネームスペースを作れるらしい。
デフォルトは"/"

socket.id

API docsより

Socket#id:String
A unique identifier for the socket session, that comes from the
underlying Client.

はい。

Client側復習

io

おもむろに登場するグローバルオブジェクト。

socket.on('イベント名’, function(パラメータ){ハンドリング})

イベントのハンドリング

socket.emit('イベント名', パラメータ)

イベントの発火

クライアントはハンドリングと発火だけなのでシンプル