gpt4 book ai didi

node.js - 页面刷新时不会触发 React 客户端上的 Socket.io 断开连接

转载 作者:行者123 更新时间:2023-12-02 16:26:37 26 4
gpt4 key购买 nike

我有 React.js + Node.js 应用程序,我在其中使用 Socket.io 通知 UI 端后端发生了一些更改,它应该提取这些更改。我在套接字中使用客户端 ID 作为标识符,因此我不必在服务器端维护用户映射。

当用户登录时,我正在建立连接并且此工作流程运行良好。问题发生在用户刷新页面时。在客户端套接字端的 Chrome 浏览器中,“断开连接”不会触发,套接字也不会重新连接。在 FF 断开连接在第一次刷新时触发,但在客户端未检索到连接成功,并且在客户端未收到通知。在第二次和以后的每一次刷新中,都不会触发断开连接。

我的客户端代码:

const io = require('socket.io-client');

export default function () {
const socket = io.connect(process.env.REACT_APP_BACKEND_URL);

function registerDisconnectHandler(onDisconnect) {
socket.on('disconnect', () => {
console.log('Disconnected');
onDisconnect();
});
}
function registerJoinHandler(onJoinSuccess) {
socket.on('joinsuccess', (msg) => {
console.log('join success');
onJoinSuccess(msg);
});
}
function joinNotification(channel, cb) {
console.log(`emit join for channel:${JSON.stringify(channel)}`);
socket.emit('joinnotificationpharmacy', channel, cb);
}
function registerNotificationHandler(onNotificationReceived) {
socket.on('notification', (notification) => {
onNotificationReceived(notification);
});
}
socket.on('error', (err) => {
console.log('received socket error:');
console.log(err);
});

return {
registerDisconnectHandler,
registerNotificationHandler,
registerJoinHandler,
joinNotification
};
}

服务器端:

const socketIo = require('socket.io');

class SocketService {
constructor(server) {
this.io = socketIo(server);
this.io.on('connect', socket => {
socket.on('joinnotificationpharmacy', function(data){
console.log('JOIN CLIENTID:'+data+" SOCKET ID:"+socket.id);
socket.join(data);
socket.emit('joinsuccess', socket.id);
});
socket.on('disconnect', function(){
console.log("client has disconnected:"+socket.id);
});
});
this.io.on('connect_error', function(err) {
// handle server error here
console.log('Error connecting to server');
});
}

sendSocketNotification(receiver, notification){
this.io.sockets.in(receiver).emit('notification', notification);
}
}

module.exports = SocketService;

服务器端的日志表明一个客户端加入了服务器,但是当刷新发生时,多个用户断开连接,这在我看来很奇怪并且看起来像是潜在的问题:

服务器端日志:

JOIN CLIENT:5f6cb94d1bb5adbab7866a14 ID:p9hC0OTKztwGlalWAAAa
client has disconnected:fJKV3MkJ4bxemZ4sAAAD
client has disconnected:xJ7bJvSqwXBbkxOhAAAI
client has disconnected:HkwouVqEXBeKvkHsAAAG
client has disconnected:9dd6e8huPveN8aVjAAAe
client has disconnected:jAZy4FXTC2oRd0a_AAAd
client has disconnected:Doonmd-ogmIRXU7iAAAc
client has disconnected:G-tc_RbO_99mivQyAAAb
client has disconnected:p9hC0OTKztwGlalWAAAa
client has disconnected:OYo2uOxuFzMeYtUEAAAW
client has disconnected:54HLS2-KHAWJ5NmqAAAR
client has disconnected:92veurywX4LhfK4cAAAg
client has disconnected:Ox73Zt-lMB0rFeA-AAAf

关于如何正确处理客户端断开连接和重新初始化连接的一些建议,我将不胜感激。

更新:

我已经找到了解决这个问题的方法,但如果有人有更好的主意,我们仍然欢迎。我添加了一个代码来标识页面重新加载并更改 redux 状态,该状态标识该连接不再存在。

  useEffect(() => {
if (sessionStorage.getItem('is_reloaded')) {
console.log('Reloaded!');
dispatch(disconnectNotificationsSocket(globalSocket, notifications.activeSocket));
}
sessionStorage.setItem('is_reloaded', true);
}, []);

最佳答案

只是指出一些事情(这里的文档可能会更好)

socket.on('disconnect', () => {
console.log('Disconnected');
onDisconnect();
});

不应该在客户端,这是在用户断开连接时为服务器保留的。

当您“重新加载”页面时,每次都会触发“断开连接”事件,这是默认行为。您在客户端连接的脚本应该再次运行并重新加入套接字服务器,就像它最初所做的那样,尽管使用不同的套接字。所以你真的不需要考虑太多,就像他们只是再次加入,而不是“重新加入”一样思考。

这真的是为了页面重新加载,现在如果用户断开连接,说他们掉线或类似的东西,这就是 socket.io beforeReconnect 和 reconnect 进来的地方,它会继续尝试 ping 服务器以尝试并重新连接。在这种情况下,您可以使用客户代码重新连接,但同样,如果他们正在重新加载页面,它应该可以正常工作。

关于node.js - 页面刷新时不会触发 React 客户端上的 Socket.io 断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64343078/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com