我希望在某些组件想要订阅数据时按需创建websocket。如何以redux方式共享websocket实例?
action.js
export function subscribeToWS(url) {
return dispatch => {
let websocket = new WebSocket(url)
websocket.on('connect', () => {
websocket.send("subscribe")
}
websocket.on('message', (message) => {
dispatch(storeNewData(message))
}
}
}
我可以做这样的事情,但这需要每个新订阅的新实例。
答案 0 :(得分:3)
将持久连接对象放在一起的标准位置是中间件。而且,实际上,有几十个现有的中间件可以证明这种方法,其中大多数都列在https://github.com/markerikson/redux-ecosystem-links/blob/master/middleware.md#sockets-and-adapters。您应该能够按原样使用其中一些,或者至少作为示例使用。
答案 1 :(得分:0)
您可以查看redux-websocket-bridge
。它将Web Socket消息展开为Redux操作,并将Redux操作中继到Web Socket。
这种方法的优点:您可以将服务器上的Redux用作API端点,用更少的代码替换标准REST API。
此外,如果您的服务器未发送Flux Standard Action,您仍然可以使用redux-websocket-bridge
作为原始邮件。它适用于string
,ArrayBuffer
和Blob
。当然,您总是可以编写一个小型中间件来将它们转换为Flux标准操作,例如来自Slack RTM API的消息。
答案 2 :(得分:0)
虽然这是一个相当古老的问题,但在寻找一个例子时它会弹出好几次。正如@matthewatabet和@abguy所提到的那样,https://github.com/luskhq/redux-ws只是提到它已被弃用,你可以使用Redux Thunk,而不需要特定于web套接字的例子。
为了将来参考,我发现this article概述了一个例子,它是在一个Github仓库中实现的,从this file开始。这适用于socket.io,但直接使用Web套接字应该是类似的。
总结一下,在组件调用dispatch
中加addNewItemSocket
:
<RaisedButton
label="Click to add!" primary={true}
onTouchTap={ () => {
const newItem = ReactDOM.findDOMNode(this.refs.newTodo.input).value
newItem === "" ? alert("Item shouldn't be blank")
: dispatch(addNewItemSocket(socket,items.size,newItem))
{/*: dispatch(addNewItem(items.size,newItem))*/}
ReactDOM.findDOMNode(this.refs.newTodo.input).value = ""
}
}
/>
在操作文件中,将addNewItemSocket
声明为:
export const addNewItemSocket = (socket,id,item) => {
return (dispatch) => {
let postData = {
id:id+1,
item:item,
completed:false
}
socket.emit('addItem',postData)
}
}
要在组件的构造函数中处理来自套接字的传入消息:
socket.on('itemAdded',(res)=>{
console.dir(res)
dispatch(AddItem(res))
})
在actoins文件中,将AddItem
声明为:
export const AddItem = (data) => ({
type: "ADD_ITEM",
item: data.item,
itemId:data.id,
completed:data.completed
})
对我而言,这仍然是新的,所以任何反馈都表示赞赏。我还将使用https://github.com/luskhq/redux-ws提交PR以在此处列出示例。