我正在开发一个使用 laravel-echo 库进行套接字连接的 React Native 移动聊天应用程序。
我有一个基于函数的 EchoServer 组件,从每个页面上的自定义标题组件呈现。它通过 useEffect 钩子调用 handleNewMessage 并设置一个新的 Echo 对象来监听套接字。
let echo = new Echo({
broadcaster: 'socket.io',
client: socketio,
authEndpoint: constants.echoServer + '/broadcasting/auth',
host: constants.echoServer + ':' + constants.echoServerPort,
auth: {
headers: {
Accept: "application/json",
Authorization: `Bearer ${params.access_token}`,
}
},
});
echo
.private(channel)
.notification((notification) => {
handleNewMessage(notification);
});
console.log('Join "online" channel');
echo.join('online')
.here(users => {
if(users.find(data => data.id === params.user.id)) {
setState({
icon: ICONS.online,
color: COLORS.online
});
}
});
echo.connector.socket.on('subscription_error', (channel, data) => {
console.log('channel subscription error: ' + channel, data);
});
从套接字连接监听通知我没有任何问题。但是,由于这个组件是在上面提到的一个头组件中渲染的,所以每次渲染头时它也会创建一个新的连接。这会导致相同的通知越来越多地出现(起初我收到 1 个通知,然后是 2 个和 3 个等)
我通过对 echo 对象使用 useContext 挂钩解决了这个问题。我基本上使用 useContext 钩子作为全局变量。
后,
const [ socket, setSocket ] = useContext(SocketContext);
在创建“新 Echo”对象之前,我检查套接字是否已经有值。
if (socket){
return;
}
但是,使用此解决方案,我必须在我的父 App.js 文件中添加另一个上下文,以便:
<AuthContext.Provider value={authContext}>
<SocketContext.Provider value={[socket, setSocket]}>
<MessageStore>
<NavigationContainer>
{ user.access_token?
<MenuStack/>
:
<AuthStack/>
}
</NavigationContainer>
</MessageStore>
</SocketContext.Provider>
</AuthContext.Provider>
我可以看到嵌套上下文将来可能是一个问题(如果它们还没有),因为我已经有了 3。我想问的是,是否有更好的解决方案来检查套接字连接是否已建立不使用 useContext 钩子?
我也在想也许 useContext 不是最好的解决方案。
此外,在身份验证过程之后仅建立一次套接字连接可能是一个更好的解决方案,而不是每次都在标头中检查它。
我正在寻找有关此案例最佳实践的建议。
提前感谢您的帮助。