React中SignalR连接(含重连)时自动发送消息的实现方案
解决SignalR自动重连后无法重新加入群组的问题
解决方案概述
SignalR 的 withAutomaticReconnect() 提供了重连成功的回调事件 onreconnected,我们只需要把加入群组的逻辑抽成独立函数,在初始连接成功和重连成功时分别调用,就能保证每次连接(包括自动重连)都执行加入群组的操作。
修改后的完整代码
const [connection, setConnection] = useState(null); // 抽离加入群组的逻辑,复用在初始连接和重连场景 const addUserToGroup = async (hubConnection) => { try { await hubConnection.send(HUB_CONNECTION_TYPES.ADD_USER_TO_GROUP, { groupId: groupId, }); } catch (error) { const toastInfo = { description: HUB_CONNECTION_ERROR_MESSAGE, type: TOAST_TYPES.error, }; dispatch(addToast(toastInfo)); } }; // 创建并管理SignalR连接 useEffect(() => { const hubConnection = new signalR.HubConnectionBuilder() .withUrl(`${process.env.REACT_APP_API_URL}/hubs/hub`, { withCredentials: false, accessTokenFactory: () => getSessionAccessToken(), }) .withAutomaticReconnect() .build(); // 绑定重连成功事件:重连后自动执行加入群组 hubConnection.onreconnected(() => { addUserToGroup(hubConnection); }); const startConnection = async () => { try { await hubConnection.start(); // 初始连接成功后立即加入群组 addUserToGroup(hubConnection); } catch (error) { const toastInfo = { description: HUB_CONNECTION_ERROR_MESSAGE, type: TOAST_TYPES.error, }; dispatch(addToast(toastInfo)); } }; startConnection(); setConnection(hubConnection); // 组件卸载时清理连接并退出群组 return async () => { if (hubConnection) { await hubConnection.send(HUB_CONNECTION_TYPES.REMOVE_USER_FROM_GROUP, { groupId: groupId, }); hubConnection.stop(); } }; }, [groupId, dispatch]); // 监听服务器推送的消息 useEffect(() => { if (connection) { connection.on(HUB_CONNECTION_TYPES.RECEIVING_MESSAGE, (message) => { dispatch(message.receivingMessage); }); } }, [connection, dispatch]);
关键修改说明
- 抽离复用逻辑:把原本只在初始连接时执行的加入群组代码,封装成独立函数
addUserToGroup,避免重复编写相同逻辑。 - 监听重连事件:通过
hubConnection.onreconnected()绑定回调,重连成功后自动触发加入群组操作。 - 统一清理逻辑:把组件卸载时的连接清理逻辑移到创建连接的 useEffect 中,直接使用当前作用域的
hubConnection,避免依赖外部 state 可能导致的异步问题。
内容的提问来源于stack exchange,提问作者AppSupportGuru1995
相关产品推荐
相关产品推荐

