无法获取名称空间的已连接套接字,或者无法检索先前存储在其中的字段

时间:2016-12-09 11:00:10

标签: socket.io

我正在关注使用旧版socket.io (v0.9.17)的node.js / express / socket.io教程,在这种情况下,我总是尝试使用每个软件包的最新版本重写代码并使其适应这种变化。

该教程的应用程序包含一个聊天应用程序:经过身份验证后,用户将被重定向到聊天室列表中。他们可以在哪里创建自己的房间或加入已经创建的房间。一旦用户加入了一个房间,他将被重定向到建立套接字连接到/messages名称空间的房间页面:

var messages = io.connect(host + "/messages");

当它发生时,会发出一个连接室事件,让用户加入他选择携带的特定房间,用户名,图片和房间号(实际上是其ID):

在客户端:

messages.on('connect', function(){
    console.log('Socket connection established on the client on room!!');
    messages.emit('joinroom', {room:roomNum, user:userName, userPic:userPic})});
});

并且在服务器端,发送的用户数据附加到套接字本身:

     var messages = io.of('/messages').on('connection', function(socket) {

                     socket.on('joinroom', function(data) {
                     socket.username = data.user;
                     socket.userPic = data.userPic;

                     // logging the socket at this level
                     console.log('### 000 ------> socket : ' + simpleStringify(socket) + '\n\n');      


                         console.log('user : ' + data.user + ' gonna join room : ' + data.room);
                         socket.join(data.room);
                         updateUserList(data.room, true);                         
                 });
}

显示套接字的日志显示其他字段中的所有用户数据

### 000 ------> socket : {"id":"/messages#wGAKwTtHtYdO7NL6AAAC","connected":true
,"disconnected":false,"_eventsCount":3,"username":"Crystaleez Comptedetestt","us
erPic":"https://scontent.xx.fbcdn.net/v/t1.0-1/c23.14.178.178/s50x50/224774_1129
37845457338_611202_n.jpg?oh=0c8b07b2b1bdfbd2e7b4c874d2045507&oe=58B8DBD9"}

在用户加入会议室之后编写的updateUserList函数主要用于检索聊天室中所有连接的客户端(或套接字)(在v0.9.17中这样做是这样的:

var clients = io.sockets.clients('room'); // all users from room `room` 

并使userList返回到客户端以刷新聊天的用户列表:

var userlist = [];
for(var i in clients) {
    userlist.push({user:clients[i].username, userPic:[clients[i].userPic});
}
socket.to(room).emit('updateUserList', JSON.stringify(userlist));

但是在最近的版本中它变成了以下内容:

io.of('/chat').clients(function(error, clients){
  if (error) throw error;
  console.log(clients); // => [PZDoMHjiu8PYfRiKAAAF, Anw2LatarvGVVXEIAAAD] 
});

这就是我在updateUserList功能代码上使用的内容,但是当我试图获得房间套接字本身并不可能时我尝试了几种方式(我给了作为在每个案例(AAA)(BBB)(CCC)之前编写的日志的标签(PS:我使用simpleStringify function来避免Converting circular structure to JSON问题当使用JSON.stringify()来记录js对象时:

function updateUserList(room, updateAll) {

     io.of('/messages').clients(function(error, clients) {
                     if (error) throw error;                         

                     console.log('\n\n\n\n(AAA)******* USING Object.keys(io.sockets.sockets) ********');
                     Object.keys(io.sockets.sockets).forEach(function(id) {
                        console.log("ID:",id)  // socketId
                        console.log('### 444 ------> socket[ID] : ' + simpleStringify(io.sockets.sockets[id]));
                    })

                     console.log('\n\n\n\n(BBB)******* USING socket_ids = Object.keys(io.of(\'/namespace\').sockets ********');
                     var socket_ids = Object.keys(io.of('/messages').sockets);
                     console.log('### 555 ------> socket_ids : ' + socket_ids);
                     socket_ids.forEach(function(socket_id) {
                         console.log("socket_id:" + socket_id)  // socketId
                         console.log('### 444 ------> socket[ID] : ' + simpleStringify(io.of('/namespace').sockets[socket_id]));

                     });


                     console.log('\n\n\n\n(CCC)******* USING Object.keys(io.sockets.connected)  ********');
                     var allConnectedClients = Object.keys(io.sockets.connected);
                     console.log('### 666 ------> allConnectedClients : ' + allConnectedClients);

                     allConnectedClients.forEach(function(socket_id) {
                         var socket = io.sockets.connected[socket_id];

                         console.log('\n\n socket_id : ' + socket_id + ' ------> socket : ' + simpleStringify(socket));
                         console.log('\n\n socket_id : ' + socket_id + ' ------> connected : ' + socket.connected);
                         /*if (socket.connected) {
                             // Do something...
                         }*/
                     });

                    //here is the code waiting for the sockets to be retrieved to work.. 
                     /*var userlist = [];
                    for(var i in clients) {
                        userlist.push({user:theMissingSocket.username, userPic:theMissingSocket.userPic});
                    }
                    socket.to(room).emit('updateUserList', JSON.stringify(userlist));

                    if(updateAll) socket.broadcast.to(room).emit('updateUserList', JSON.stringify(userlist));*/
                 });

             }

对于(AAA)和(CCC)情况,可以检索套接字,但是没有上面添加的用户数据,这里是他们的记录(只有" id","连接"和"光盘     onnected"遗体):

(AAA)******* USING Object.keys(io.sockets.sockets) ********
ID: IaLjQS2IxQI3FcYSAAAB
### 444 ------> socket[ID] : {"id":"IaLjQS2IxQI3FcYSAAAB","connected":true,"disc
onnected":false}
ID: wGAKwTtHtYdO7NL6AAAC
### 444 ------> socket[ID] : {"id":"wGAKwTtHtYdO7NL6AAAC","connected":true,"disc
onnected":false}


(CCC)******* USING Object.keys(io.sockets.connected)  ********
### 666 ------> allConnectedClients : IaLjQS2IxQI3FcYSAAAB,wGAKwTtHtYdO7NL6AAAC


 socket_id : IaLjQS2IxQI3FcYSAAAB ------> socket : {"id":"IaLjQS2IxQI3FcYSAAAB",
"connected":true,"disconnected":false}


 socket_id : IaLjQS2IxQI3FcYSAAAB ------> connected : true


 socket_id : wGAKwTtHtYdO7NL6AAAC ------> socket : {"id":"wGAKwTtHtYdO7NL6AAAC",
"connected":true,"disconnected":false}
对于(BBB)案例,我根本无法获得套接字:

(BBB)******* USING socket_ids = Object.keys(io.of('/namespace').sockets ********

### 555 ------> socket_ids : /messages#wGAKwTtHtYdO7NL6AAAC
socket_id:/messages#wGAKwTtHtYdO7NL6AAAC
### 444 ------> socket[ID] : {}

1 个答案:

答案 0 :(得分:1)

您可以尝试以下功能:

function findClients(room, namespace) {
    'use strict';
    var res = [];
    var ns = io.of(namespace || "/");

    if (ns) {
        Object.keys(ns.connected).forEach(function (id) {
            if (room) {
                var roomKeys = Object.keys(ns.connected[id].rooms);
                roomKeys.forEach(function (key) {
                    if (key === room) {
                        res.push(ns.connected[id].client.id);
                    }
                });
            } else {
                res.push(ns.connected[id].client.id);
            }
        });
    }
    return res.sort();
}

并在一个简单的例子中测试它:

server.js

const io = require('socket.io')(3000);
var counter = 0;

function findClients(room, namespace) {
    'use strict';
    var res = [];
    var ns = io.of(namespace || "/");

    if (ns) {
        Object.keys(ns.connected).forEach(function (id) {
            if (room) {
                var roomKeys = Object.keys(ns.connected[id].rooms);
                roomKeys.forEach(function (key) {
                    if (key === room) {
                        res.push(ns.connected[id].client.id);
                    }
                });
            } else {
                res.push(ns.connected[id].client.id);
            }
        });
    }
    return res.sort();
}

io.of('/messages').on('connection', function (socket) {
    'use strict';
    socket.join('room' + (counter % 2));
    console.log(socket.client.id + ' connected to room' + (counter % 2));
    counter += 1;
    setTimeout(function () {
        console.log('Clients connected to room0: ' + findClients('room0', '/messages'));
        console.log('Clients connected to room1: ' + findClients('room1', '/messages'));
    }, 0);
});
console.log('Plain socket.io server started at port 3000');

client.js

const socket = require('socket.io-client')('http://localhost:3000/messages');
socket.on('connect', function () {
    console.log('connected');
});

运行client.js的多个实例并检查服务器消息。它似乎可以按你的需要工作。