从 Nodejs socketio 数组获取所有套接字 id

Getting all sockets id from Nodejs socketio array

本文关键字:套接字 id 获取 Nodejs socketio 数组      更新时间:2023-09-26

我正在使用socketio 0.9创建一个复杂的程序,为了存储所有套接字id,我使用了这样的数组:

var clients = {};

使用自己的串行来识别我的套接字并将它们存储在我的数组中,然后我设置"套接字"键,具有它的实际值。

clients[serial] = { "socket": socket.id };

现在我需要从我的数组中获取所有套接字 id,而无需其串行。我该怎么做?

我正在尝试这个迭代,但我不知道如何获取套接字属性:

for(var c in clients) {
c.socket
}

谢谢。

这不是 JavaScript 中的数组

虽然PHP称其为关联数组,但它在JavaScript中只是一个对象(也称为哈希(,在理论计算机科学中只是一个哈希哈希映射

用于 ...在

话虽如此,for ... in指令遍历对象的,而不是其

var clients = {
  clientid1: { name: "John Doe", age: 42 },
  clientid2: { name: "Jane Doe", age: 34 }
};
for (var key in clients) {
  console.log(key);
}
Console output:
  "clientid1"
  "clientid2"

因此,若要访问客户端哈希的值(如 socket 属性(,请像这样迭代它:

for (var serial in clients) {
  clients[serial].socket.sendSomethingViaTheSocket(...);
}

好吧,for ... in似乎有效,为什么存在其他解决方案?

由于 JavaScript 是一种具有原型

继承的非常动态的语言,因此您可以添加、更改和删除几乎每个 JavaScript 对象的属性,并向对象原型添加新的属性和方法(某个"类"对象具有的方法和属性的"蓝图"(。

这意味着这是完全有效的 JavaScript 代码:

HTMLElement.prototype.isParagraph = false;
HTMLParagraphElement.prototype.isParagraph = true;
var myElement = document.querySelector(...);
if (myElement.isParagraph) {
  // that's possible in javascript!
}

由于 JavaScript 中的大多数对象都允许扩展原型,因此 Object 原型也是可能的,它是所有非值对象的祖先。假设您想定义自己的方法来向对象添加属性(为什么您决定这样做(:

Object.prototype.addProperty = function (name, value) {
  this[name] = value;
};
var exampleCustomer = { name: "John Doe" };
exampleCustomer.addProperty("age", 42);
console.log(exampleCustomer.age);    // logs 42 on the console

但这意味着从现在开始 JavaScript 中的每个对象都有一个 addProperty 方法,因此当你使用 for ... in 时,你不会得到你期望的结果:

for (var key in exampleCustomer) {
  console.log('key ', key, ' equals ', exampleCustomer[key]);
}
Console output:
  key name equals John Doe
  key age equals 42
  key addProperty equals function (name, value) { ... }
       ^ oops!

现在,您会发现for ... in还会迭代在要迭代的对象原型链上设置的属性。这意味着使用for ... in是可以的,当且仅当您可以确定没有人更改您的原型时。

ES5:Object.defineProperty 和 Object.defineProperties

从 ES5 开始,有两种方法可以缓解该问题。遇见Object.definePropertyObject.defineProperties .如果需要在原型上定义方法,请使用以下方法:

Object.defineProperty(
  Object.prototype, // the object the property should be defined on
  "addProperty", // name of the property
  {
    enumerable: false, // should the property show up in for ... in / Object.keys()?
    writable: true, // can the value of this property be changed with obj.addProperty = ..?
    configurable: true, // can this property be changed with another defineProperty call?
    value: function (name, value) { this[name] = value; }
  }
);

使用 configurable: false 定义属性时,它不会显示在for ... in循环中。

解决原型问题的解决方案(本机 JavaScript(

如果您不想使用库来解决上述问题,则可以使用vanilla JavaScript中包含的一些方法。

Object.keysArray.prototype.forEach

Object.keys(clients).forEach(function (key) {
  clients[key].socket.sendSomething();
});
// will NOT iterate over prototype-inherited properties

ECMAScript2015/ECMAScript6 for ... of(适用于节点 4+ 和新浏览器,没有 IE(

for (let clientid of clients) {
  clients[clientid].socket.sendSomething();
}

也不迭代原型继承的属性

您还可以在节点 4+ 中使用 Array.prototype.map箭头函数,以非常易读的方式获取所有客户端的套接字:

let clientSockets = Object.keys(clients).map(k => clients[k].socket);
// clientSockets contains the socket of all clients now

解决原型问题的解决方案 (库(

下划线/短划线:

_.each(clients, function (client) {
  client.socket.sendSomething();
});

j查询:

$.each(clients, function (id, client) {
  client.socket.something();
});

AngularJS:

angular.forEach(clients, function (client, id) { // order is different than with jQuery!
  client.socket.something();
});

您可以像这样创建保存的所有套接字ID的数组:

var arr = [];
Object.keys(clients).forEach(function(s){
    arr.push(clients[s].socket)    
});
console.log(arr); // arr would have all socketIds

在这里,Object.keys(( 返回客户端中所有序列的数组,然后用于迭代并查找您保存的每个套接字 Id 值

首先,clients不是一个数组,而是一个对象。

您可以通过Object.keys()或从可以使用

_.keys lodash获得一点帮助,或者如果您只对套接字 ID 感兴趣:

let _ = require('lodash');
console.log(_.map(clients, 'socket');