前言
最近有个项目碰到了几个挺有趣的库,特别是socket.io-client,一开始看文档的第一感觉:很简单嘛!
但是其中遇到一个问题,让我让我大受挫败,情景就是登录后在main页面带上token连接socket,并且需要在其他页面监听其他事件。
事情起因经过
直接上代码
import { io } from 'socket.io-client';
const getSocket = () => {
let token: string = sessionStorage.getItem('Authorization') || '';
const socket = io(process.env.NODE_ENV === 'production' ? 'url' : 'url', {
transports: ['websocket', 'polling'],
auth: {
// token: 'Bearer ' + token,
Authorization: token,
},
reconnection: true,
});
return socket;
};
export default getSocket;
然后在main页面:
let id = session;
console.log(id);
socket.on('connect', () => {
if (id) {
socket.emit('room', {
action: 'join',
data: {
roomId: id,
},
});
}
});
socket.on('message', handleMessage);
socket.on('disconnect', () => {
});
return () => {
socket.off('message');
socket.off('connect');
socket.off('disconnect');
};
}, [dispatch, navigate, session, handleMessage]);
导致的结果是main页面useEffect由于useCallback(handleMessage,[a,b])以来的变量导致useEffect渲染两次,socket connet了两次,socket.on监听的事件根本监听不到,更别说其他组件了。在做进度汇报的时候提到这个问题被大佬一眼看透:这个应该是useEffect重复渲染导致的,前后端的socket id应该要同一个才能互相发送消息。我一看network ws竟然有多个socket连接,当场尬住。。。
总结
总结:在使用不熟悉的框架前多看些成熟案例,遇到问题时多试几种排错方式,如果早点意识到有多个socket连接,明明websocket是个长链接。。。