简体   繁体   English

带Websockets的Redux-thunk

[英]Redux-thunk with Websockets

I want to create a websocket on demand when certain components want to subscribe to data. 我希望在某些组件想要订阅数据时按需创建websocket。 How can I share the websocket instance in a redux fashion? 如何以redux方式共享websocket实例?

action.js 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))
      }
   } 
}

I could do something like this, but this would require a new instance for every new subscription. 我可以做这样的事情,但这需要为每个新订阅一个新实例。

The standard place to put things like persistent connection objects is inside middleware. 放置持久连接对象之类的标准位置是在中间件中。 And, in fact, there's literally dozens of existing middlewares that demonstrate that approach, with most of them listed over at https://github.com/markerikson/redux-ecosystem-links/blob/master/middleware.md#sockets-and-adapters . 而且,实际上,有几十个现有的中间件可以证明这种方法,其中大多数都列在https://github.com/markerikson/redux-ecosystem-links/blob/master/middleware.md#sockets-and -adapters You should be able to use some of those as-is, or at least as examples. 您应该能够按原样使用其中一些,或者至少作为示例使用。

You can look at redux-websocket-bridge . 你可以看看redux-websocket-bridge It unfold Web Socket messages into Redux action, and relay Redux action to Web Socket. 它将Web Socket消息展开为Redux操作,并将Redux操作中继到Web Socket。

Upside of this approach: you can use Redux on your server as API endpoint, replacing standard REST API with less code. 这种方法的优点:您可以在服务器上使用Redux作为API端点,用更少的代码替换标准REST API。

Also, if your server do not send Flux Standard Action , you can still use redux-websocket-bridge for raw messages. 此外,如果您的服务器不发送Flux标准操作 ,您仍然可以使用redux-websocket-bridge作为原始消息。 It works with string , ArrayBuffer , and Blob . 它适用于stringArrayBufferBlob Of course, you can always write a small middleware to translate them into Flux Standard Action, eg messages from Slack RTM API. 当然,您总是可以编写一个小型中间件来将它们转换为Flux标准操作,例如来自Slack RTM API的消息。

Although this is quite an old question by now, it popped up several times when looking for an example. 虽然这是一个相当古老的问题,但在寻找一个例子时,它突然出现了几次。 As @matthewatabet and @abguy mention, https://github.com/luskhq/redux-ws just mentions it has been deprecated and you can use Redux Thunk, without an example specific for web sockets. 正如@matthewatabet和@abguy所提到的, https://github.com/luskhq/redux-ws刚刚提到它已被弃用,您可以使用Redux Thunk,而不需要特定于Web套接字的示例。

For future reference, I found this article that outlines an example, that is implemented in a Github repo, starting on this file . 为了将来的参考,我发现这篇文章概述了一个例子,它是在一个Github仓库中实现的,从这个文件开始。 This is for socket.io, but using web sockets directly should be similar. 这适用于socket.io,但直接使用Web套接字应该是类似的。

Summarizing, in the Component call dispatch with addNewItemSocket : 总结一下,在Component调用中使用addNewItemSocket dispatch

<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 = ""
      }
    }
/>

In the actions file, declare addNewItemSocket as: 在actions文件中,将addNewItemSocket声明为:

export const addNewItemSocket = (socket,id,item) => {
    return (dispatch) => {
        let postData = {
                id:id+1,
                item:item,
                completed:false
             }
        socket.emit('addItem',postData)     
    }   
}

To handle incoming messages from the socket, in the constructor of the component: 要处理来自套接字的传入消息,请在组件的构造函数中:

socket.on('itemAdded',(res)=>{
   console.dir(res)
   dispatch(AddItem(res))
})

And in the actoins file, declare AddItem as: 在actoins文件中,将AddItem声明为:

export const AddItem = (data) => ({
    type: "ADD_ITEM",
    item: data.item,
    itemId:data.id,
    completed:data.completed
})

For me this is still new, so any feedback is appreciated. 对我而言,这仍然是新的,所以任何反馈都表示赞赏。 I will also file a PR with https://github.com/luskhq/redux-ws to have an example listed there. 我还将通过https://github.com/luskhq/redux-ws提交PR以在此处列出示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM