我正在尝试在我的React / Redux / redux saga应用中实现Pusher的消息传递库Chatkit,而我是Redux的新手。连接到chatkit的代码如下:
const chatManager = new ChatManager({
instanceLocator: 'v1:us1:80215247-1df3-4956-8ba8-9744ffd12161',
userId: 'sarah',
tokenProvider: new TokenProvider({ url: 'your.auth.url' })
})
chatManager.connect()
.then(currentUser => {
console.log('Successful connection', currentUser)
})
.catch(err => {
console.log('Error on connection', err)
})
我需要全局存储chatManager和currentUser对象(它们是具有功能的复杂类的实例),以便以后可以再次使用它们来加入会议室,订阅事件等。
我首先想到的是我应该将其存储在Redux中,因为它现在是我的“全局存储”,但是后来我意识到它可能无法工作,因为它不是我从存储中取出的原始对象,它大概是一个克隆。然后我读到,显然只有普通对象应该存储在Redux中。
那么,不是普通对象但需要全局存储的对象在哪里呢?我不想将它们放在window对象上,因为我可能会将其转换为React Native应用程序,而且看起来还是很混乱。
答案 0 :(得分:7)
根据Redux FAQ entry on storing "connection"-type objects:
出于以下几个原因,中间件是Redux应用程序中进行websockets之类的持久连接的正确位置:
- 在应用程序的生存期内存在中间件
- 就像商店本身一样,您可能只需要整个应用程序可以使用的给定连接的单个实例
- 中间件可以查看所有已调度的动作和本身的调度动作。这意味着中间件可以采取调度的动作,并将其转换为通过websocket发送的消息,并在通过websocket接收消息时调度新的动作。
- websocket连接实例不可序列化,因此它不属于存储状态本身
修改
这是我的“示例套接字中间件”示例,已更新为延迟创建套接字,直到看到登录操作为止。
const createMySocketMiddleware = (url) => {
let socket;
return storeAPI => next => action => {
switch(action.type) {
case "LOGIN" : {
socket = createMyWebsocket(url);
socket.on("message", (message) => {
storeAPI.dispatch({
type : "SOCKET_MESSAGE_RECEIVED",
payload : message
});
});
break;
}
case "SEND_WEBSOCKET_MESSAGE": {
socket.send(action.payload);
return;
}
}
return next(action);
}
}