WebSocket 需要浏览器刷新来更新列表

WebSocket needs browser refresh to update list

我的项目按预期工作,除了每次我的关键字列表向其发送要显示的内容时我都必须刷新浏览器。我认为这是我对 Expressjs 缺乏经验并且没有在我的 websocket 中正确创建路由?任何帮助将不胜感激。

浏览器

let socket = new WebSocket("ws://localhost:3000");

socket.addEventListener('open', function (event) { 
  console.log('Connected to WS server')
  socket.send('Hello Server!'); 
}); 

socket.addEventListener('message', function (e) {
  const keywordsList = JSON.parse(e.data);
  console.log("Received: '" + e.data + "'");
  document.getElementById("keywordsList").innerHTML = e.data;
}); 

socket.onclose = function(code, reason) {
  console.log(code, reason, 'disconnected');
}

socket.onerror = error => {
  console.error('failed to connect', error);
}; 

服务器

const ws = require('ws');
const express = require('express');
const keywordsList = require('./app');

const app = express();
const port = 3000;

const wsServer = new ws.Server({ noServer: true });
wsServer.on('connection', function connection(socket) {
  socket.send(JSON.stringify(keywordsList));
  socket.on('message', message => console.log(message));
});

// `server` is a vanilla Node.js HTTP server, so use
// the same ws upgrade process described here:
// https://www.npmjs.com/package/ws#multiple-servers-sharing-a-single-https-server
const server = app.listen(3000);
server.on('upgrade', (request, socket, head) => {
  wsServer.handleUpgrade(request, socket, head, socket => {
    wsServer.emit('connection', socket, request);
  });
}); 

回答“如何发送 and/or 不断更新到客户端的流数组数据”,如评论中所述。

使用 WebSockets 的可能解决方案是

  1. 在服务器上为数组更新创建一个接口(如果您还没有的话),将数组对象与任意外部修改隔离开来,并在进行更新时支持回调。

  2. 确定允许在不推送的情况下发生多个更新的延迟。延迟应为之前的网络流量留出合理的时间来完成,而不会不必要地使带宽过载。

  3. 当阵列更新发生时,启动一个定时器如果还没有运行等待延迟时间。

  4. 在计时器到期时 JSON.stringify 阵列(拍摄快照),清除计时器 运行 状态,并使用 JSON 文本向客户端发送消息。

避免延迟所有推送操作的稍微复杂的方法是立即推送单个更新除非它们发生在最近推送操作后的保护期内。计时器可以然后在保护期结束时推送保护期内的修改。


广播

WebSockets API 不直接支持向多个客户端广播相同的数据。请参阅 ws 文档中的 Server Broadcast,了解使用 forEach 循环向所有连接的客户端发送数据的示例。


客户端侦听器

在客户端消息监听器中

document.getElementById("keywordsList").innerHTML = e.data;

会更好

document.getElementById("keywordsList").textContent = keywordList;

从 JSON 解码后显示关键字并防止它们被视为 HTML。

所以我终于弄清楚了我想要完成的事情。在我充分了解并思考如何构建我的项目后端之后,这听起来很简单。

如果你有两个 websockets 运行ning 并且一个需要另一个的信息,你不能 运行 它们并排。您需要让一个封装另一个,然后调用另一个 websocket 的 websocket INSIDE。这很容易给其他项目带来问题,因为现在你有一个 websocket 在另一个 运行 之前不会触发,但对于我的项目来说它非常有意义,因为它在本地 运行 并且需要为了有效,所有部件都 100% 工作。我花了很长时间才理解如何构造代码。