尽管收到了来自服务器的消息,但 Chrome 的 onmessage() 不会在重新连接后立即触发
Posted
技术标签:
【中文标题】尽管收到了来自服务器的消息,但 Chrome 的 onmessage() 不会在重新连接后立即触发【英文标题】:Chrome's onmessage() does not fire immediately after reconnect, despite receiving a message from the server 【发布时间】:2019-11-04 10:20:46 【问题描述】:我目前正在尝试在 chrome 和 NodeJS 服务器之间创建一个 websocket。 Node 服务器使用的是ws 插件,而我使用的是 Chrome 的默认 websocket 处理程序。
这是我的服务器代码行:
wss.on('connection', function connection(ws)
ws.id = uuid();
let response = 'type': 'uuid','data': ws.id;
ws.send(JSON.stringify(response));
);
我的客户代码:
//Listens for new messages
connection.onmessage = function(e)
let data = JSON.parse(e.data);
console.log(data.data);
我的期望:每次创建连接时,服务器都会为客户端生成一个 UUID,然后客户端将其打印到控制台。当连接断开并且客户端重新连接时,服务器会向客户端发送一个新的 UUID。
发生了什么:服务器在创建连接时为客户端生成一个 UUID,然后客户端将其打印到控制台。但是,当服务器宕机并重新启动,并且客户端重新建立连接时,服务器确实会向客户端发送一个新的 UUID,但 chrome 并没有接收到它。
任何帮助将不胜感激。谢谢!
编辑:这就是我重新连接到服务器的方式
//Reconnect to server
setInterval(function()
if (connection.readyState !== WebSocket.OPEN)
reconnect = false;
connection.close();
console.log("Disconnected from server. Retrying...");
connection = new WebSocket(server);
else
if (!reconnect)
reconnect = true;
console.log("Reconnected to server.");
, 1000);
编辑2:修改了代码,还是不行:
//Webhook
//On connection open
connection.onopen = function()
console.log("Connected to server");
reconnect = "";
//Reconnect to server if disconnected
connection.onclose = function(e)
console.log("Connection closed, reconnecting...");
//Retry every second
reconnect = setInterval(function()
if (connection.readyState !== WebSocket.OPEN)
connection.close();
console.log("Connecting to server...");
connection = new WebSocket(server);
, 1000);
onopen()
也不会在重新连接时触发,因此客户端会在断开连接后每秒尝试重新连接,并且永远不会停止。
【问题讨论】:
如果客户端重新连接到服务器,您确定在新连接上设置了onmessage
监听器吗?您能否在问题中包含重新连接处理?
实现我会尽快回复你@Seblor
@Seblor 我该怎么做呢?我是否将onmessage
包装成onopen
?我添加了我重新连接到上面主要问题的方式。
没错。当 websocket 打开它的连接时,你应该初始化所有的监听器。
另外,您可以向onclose
事件添加侦听器,而不是使用 setInterval 来检查连接是否仍然存在,该事件将在服务器关闭(或崩溃)时触发,然后尝试重新连接(如果您想多次尝试以防第一次失败,可以使用 setinterval )。这在性能方面会更好,因为您不必每次都执行相同的检查。
【参考方案1】:
我找到了解决办法
//Webhook
function connect()
//Attempt to connect to server
if (firstConnect)
console.log("Connecting to server...");
connection = new WebSocket(server);
else
if (connection.readyState !== WebSocket.OPEN)
connection.close();
console.log("Connecting to server...");
connection = new WebSocket(server);
//On connection open
connection.onopen = function()
firstConnect = false;
console.log("Connected to server");
clearInterval(reconnect);
//Listens for new messages
connection.onmessage = function(e)
//Reconnect to server if disconnected
connection.onclose = function(e)
console.log("Connection closed, reconnecting...");
connect();
当您创建新的套接字连接时,chrome 会反复尝试自行连接,直到超时。超时将触发connection.onclose
,然后调用connect()
。
通过将其全部嵌套在 connect()
中,事件处理程序将每次都挂接到新的 websocket 连接上。此外,您不需要setInterval()
,从而避免任何性能问题。
经过测试的浏览器:Chrome、Opera、Safari
【讨论】:
以上是关于尽管收到了来自服务器的消息,但 Chrome 的 onmessage() 不会在重新连接后立即触发的主要内容,如果未能解决你的问题,请参考以下文章
找出 Profobuf 消息的类型(Google Chrome 同步)
尽管我使用了有效的令牌,但 Laravel Passport 得到未经身份验证的响应