我目前正在为移动前端创建一个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);
});```
好的。 仍在尝试了解您要拍摄的实际规格。 但是,假设以下内容(基于您对我之前问题的回答(:
- 客户端使用 webSocket 进行连接。
- 当他们通过该 webSocket 发送消息时,该消息是可以在数据库中查找的内容的
id
,并且他们希望定期更新。 - 该特定
id
的这些更新应仅发送到请求它的特定客户端。 - 如果不同的客户端连接并指定了某些
id
,则它们应仅获取该id
的更新。 - 当客户端发送指定不同
id
的新消息时,他们的更新现在应该只针对该新id
。 - 一个客户端请求的
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);
}
});
});
现在,一些评论:
在短时间间隔内轮询数据库,并为每个客户端使用单独的轮询循环根本不会扩展。 您将遇到严重的数据库缩放问题。 您确实需要更好的设计,但由于我们不知道应用程序的总体要求和体系结构,因此我们没有足够的信息来了解该建议的内容。 您可能希望利用数据库中的通知来告诉您数据何时更改,而不是代表每个客户端在短时间间隔内轮询它。
我找不到
lookup
数据结构的原因。 您的注释说您要将更新发送到一个特定客户端,即请求该 id 的客户端。 这可以通过ws.send()
.此代码假定
client
变量表示与数据库的连接,每个连接的客户端的每个 setIntervals 都可以共享该连接。 这就是将该代码移出wss.on('connection', ...)
事件处理程序的原因。我切换到更常见的术语
wss
来指代服务器实例,ws
指代特定连接客户端的 webSocket。ws.send()
是发送到连接的客户端的方式。 我仍然不知道你对op.id
做了什么. 查看ws
库的文档,这似乎不是您可以用来发送到的内容。您的代码(以及此代码(为每个连接的 webSocket 客户端创建一个单独的
setInterval()
计时器,并且它使用非常短的间隔时间。 这不会缩放。 在最坏的情况下,间隔时间需要延长到几秒钟(取决于所需的目标尺度(。 充其量,您需要完全停止轮询数据库,并在数据库中使用其他机制在数据发生更改时获取通知。