Socket.ioからユーザーの一覧を取得(ソケットIDのリスト)
前回のエントリーでは全て Node.js のサーバ内で検証していたが、実際にはクライアントサイドの Javascript とデータをやり取りしてこそだ。
と言う訳で、手始めにユーザーがページを開いた時、既に繋がっているユーザー(ソケットID)のリストを取得してみようと思う。
前回同様 PHPで作ったサイトでSocket.ioを使いたい 内に掲載した「server.js のソース」に加えて「client.js」のソースもいじくり回している。
adapter.sids をそのまま emit する(失敗)
まずはいつも通り、シンプルに行く。
// server.js
io.of("/").on("connection", socket => {
io.to(socket.id).emit("test1", io.of("/").adapter.sids);
});
// client.js
socket.on("test1", sids => console.log(sids));
これで実行、流石に楽勝ですね。
# dev tool console
{}
あれ?なにこれ、中身が消えてる??
サーバ側から渡す値のところ、直接書くのがいけないのだろうか。
// server.js
io.of("/").on("connection", socket => {
const sids = io.of("/").adapter.sids;
console.log(sids);
io.to(socket.id).emit("test1", sids);
});
変数に一旦格納してから渡してみる。
$ node server.js
Map(1) { '<socket.id-A>' => Set(1) { '<socket.id-A>' } }
渡す直前では中身が入っている事も確認出来る。
# dev tool console
{}
なんでや!
サーバ側のコンソールでは、渡す直前も中身が入ってる事が確認出来るのに、どう言う訳かブラウザ(クライアント)には空っぽのオブジェクトが渡されてしまうようだ。
型変換してから emit する(成功)
ここは管理人の勉強不足で申し訳ないが、Map 型や Set 型だと送れないとか、そんな仕様が有ったりするのだろうか。
折角なので試してみよう。
// server.js
io.of("/").on("connection", socket => {
const sids = io.of("/").adapter.sids;
const param = [];
sids.forEach((val, key) => param.push({id: key, join: val}));
io.to(socket.id).emit("test1", param);
});
Map 型をシンプルな Array 型に変換するため、forEach で全件ぐるぐるしながら key と val に分解しつつ push してみた。
# dev tool console
[{
0:
id: "<socket.id-A>"
join: {}
}]
文字列型になった key はちゃんと受け取れているが、Set 型のままの val はやはり虚無なオブジェクトが送られて来たので、こちらも変換してやる必要があるようだ。
// server.js
io.of("/").on("connection", socket => {
const sids = io.of("/").adapter.sids;
const param = [];
sids.forEach((val, key) => param.push({id: key, join: [...val]}));
io.to(socket.id).emit("test1", param);
});
Set 型の変換には、ちょっとカッコいいかな?と思ってスプレッド演算子を使ってみたが、Array.from の方が可読性が良いかも知れない。
# dev tool console
[{
0:
id: "<socket.id-A>"
join: [ "<socket.id-A>" ]
}]
上手く受け取れて一安心。
本音を言うとサーバ側では必要最低限の処理と、必要最低限のデータを返して、クライアントサイドでゴリゴリしたかったのだが、背に腹は代えられない。
今回の学習では「なにやらそのまま送信出来ない型がある」と言う事が知れたので、大変有意義でした。
関連記事