Websocket 发送到特定用户 nodejs



我目前正在为移动前端创建一个websocket服务器。 在某些情况下,我只需要将 json 发送给特定用户,经过几次尝试,我仍然无法让 Websocket 工作,因此我可以一次将我的 json 发送到一个客户端。

我正在使用这个库:github.com/websockets/ws

为了解释我的问题,我有几个产品包含几个需要实时刷新的变量。 当用户连接到产品时,他将只收到该产品的 JSON,而其他用户将收到他们当前使用的其他产品的 JSON。 这就是为什么我想向用户发送特定的 JSON 以启用此功能

我想知道你们中是否有人知道如何解决问题,因为我开始阻止它。

谢谢。

const opp = new WebSocket.Server({port: 10001});
let user = 0;
let lookup = [];
opp.on('connection', function connection(op) {
lookup.push(op.id);
let id = "";
op.on('message', function incoming(message) {
console.log('received: %s', message);
id = message;
query = {
text: "SELECT id,state,users_list_name,user_win,timer_stamp FROM products WHERE id = " + parseInt(id) + " AND circle = 1 ORDER BY CASE WHEN state = 'available' THEN '1' WHEN state = 'soon' THEN '2' WHEN state = 'expired' THEN '3' END",
};
});
client.connect();
const interval = setInterval(function ping() {
client.query(query, (err, res) => {
if (err) {
console.log(err.toString());
console.log(query);
} else {
console.log(lookup);
for (let i = 0; i < lookup.length; i++){
console.log("########################");
lookup[i].send(JSON.stringify(res.rows));
}
}
});
}, 300);
});``` 

好的。 仍在尝试了解您要拍摄的实际规格。 但是,假设以下内容(基于您对我之前问题的回答(:

  1. 客户端使用 webSocket 进行连接。
  2. 当他们通过该 webSocket 发送消息时,该消息是可以在数据库中查找的内容的id,并且他们希望定期更新。
  3. 该特定id的这些更新应仅发送到请求它的特定客户端。
  4. 如果不同的客户端连接并指定了某些id,则它们应仅获取该id的更新。
  5. 当客户端发送指定不同id的新消息时,他们的更新现在应该只针对该新id
  6. 一个客户端请求的id的更新仅发送到该客户端(不发送到其他客户端(。

如果这是你真正想要的,这里有一种方法来构建它。

const wss = new WebSocket.Server({port: 10001});
// make database connection that all users share
client.connect();
wss.on('connection', function connection(ws) {
// these variables are unique to each ws connection
let interval, query;
// when webSocket closes, stop any current interval timer associated with this webSocket
ws.on('close', function() {
if (interval) {
clearInterval(interval);
}
});
// when we get an id, start querying for updates on that id
ws.on('message', function incoming(id) {
console.log(`received: ${id}`);
query = {
text: "SELECT id,state,users_list_name,user_win,timer_stamp FROM products WHERE id = " + parseInt(id) + " AND circle = 1 ORDER BY CASE WHEN state = 'available' THEN '1' WHEN state = 'soon' THEN '2' WHEN state = 'expired' THEN '3' END",
};
// if interval is not already going, start it
if (!interval) {
interval = setInterval(function() {
client.query(query, (err, res) => {
if (err) {
console.log(err);
console.log(query);
} else {
// send data to just the one client that this timer is for
ws.send(JSON.stringify(res.rows));
}
});
}, 300);
}
});
});

现在,一些评论:

  1. 在短时间间隔内轮询数据库,并为每个客户端使用单独的轮询循环根本不会扩展。 您将遇到严重的数据库缩放问题。 您确实需要更好的设计,但由于我们不知道应用程序的总体要求和体系结构,因此我们没有足够的信息来了解该建议的内容。 您可能希望利用数据库中的通知来告诉您数据何时更改,而不是代表每个客户端在短时间间隔内轮询它。

  2. 我找不到lookup数据结构的原因。 您的注释说您要将更新发送到一个特定客户端,即请求该 id 的客户端。 这可以通过ws.send().

  3. 此代码假定client变量表示与数据库的连接,每个连接的客户端的每个 setIntervals 都可以共享该连接。 这就是将该代码移出wss.on('connection', ...)事件处理程序的原因。

  4. 我切换到更常见的术语wss来指代服务器实例,ws指代特定连接客户端的 webSocket。

  5. ws.send()是发送到连接的客户端的方式。 我仍然不知道你对op.id做了什么. 查看ws库的文档,这似乎不是您可以用来发送到的内容。

  6. 您的代码(以及此代码(为每个连接的 webSocket 客户端创建一个单独的setInterval()计时器,并且它使用非常短的间隔时间。 这不会缩放。 在最坏的情况下,间隔时间需要延长到几秒钟(取决于所需的目标尺度(。 充其量,您需要完全停止轮询数据库,并在数据库中使用其他机制在数据发生更改时获取通知。

最新更新