带Websockets的Redux-thunk

时间:2016-06-28 19:55:34

标签: javascript reactjs redux redux-thunk

我希望在某些组件想要订阅数据时按需创建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))
      }
   } 
}

我可以做这样的事情,但这需要每个新订阅的新实例。

3 个答案:

答案 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作为原始邮件。它适用于stringArrayBufferBlob。当然,您总是可以编写一个小型中间件来将它们转换为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以在此处列出示例。