【问题标题】:Websocket as promised for redux为 redux 承诺的 Websocket
【发布时间】:2017-09-28 06:36:33
【问题描述】:

如何按照 redux 中的承诺转换这个 websocket?我想使用这个库 https://www.npmjs.com/package/websocket-as-promised ,但我不知道如何在我的 weksocket 中实现它。

我需要你的帮助,请。

这个用于 redux 的 websocket 是由 "exec64" 创建的,它在我的应用程序中可以使用,但我希望它返回一个承诺。

来源: https://exec64.co.uk/blog/websockets_with_redux/

我的中间件

import actions from './actions'

const socketMiddleware = (function(){ 
  var socket = null;

  const onOpen = (ws,store,token) => evt => {
    //Send a handshake, or authenticate with remote end

    //Tell the store we're connected
    store.dispatch(actions.connected());
  }

  const onClose = (ws,store) => evt => {
    //Tell the store we've disconnected
    store.dispatch(actions.disconnected());
  }

  const onMessage = (ws,store) => evt => {
    //Parse the JSON message received on the websocket
    var msg = JSON.parse(evt.data);
    switch(msg.type) {
      case "CHAT_MESSAGE":
        //Dispatch an action that adds the received message to our state
        store.dispatch(actions.messageReceived(msg));
        break;
      default:
        console.log("Received unknown message type: '" + msg.type + "'");
        break;
    }
  }

  return store => next => action => {
    switch(action.type) {

      //The user wants us to connect
      case 'CONNECT':
        //Start a new connection to the server
        if(socket != null) {
          socket.close();
        }
        //Send an action that shows a "connecting..." status for now
        store.dispatch(actions.connecting());

        //Attempt to connect (we could send a 'failed' action on error)
        socket = new WebSocket(action.url);
        socket.onmessage = onMessage(socket,store);
        socket.onclose = onClose(socket,store);
        socket.onopen = onOpen(socket,store,action.token);

        break;

      //The user wants us to disconnect
      case 'DISCONNECT':
        if(socket != null) {
          socket.close();
        }
        socket = null;

        //Set our state to disconnected
        store.dispatch(actions.disconnected());
        break;

      //Send the 'SEND_MESSAGE' action down the websocket to the server
      case 'SEND_CHAT_MESSAGE':
        socket.send(JSON.stringify(action));
        break;

      //This action is irrelevant to us, pass it on to the next middleware
      default:
        return next(action);
    }
  }

})();

export default socketMiddleware

我的操作类型

export const WS_CONNECTING = 'WS_CONNECTING'
export const WS_CONNECTED = 'WS_CONNECTED'
export const WS_DISCONNECTED = 'WS_DISCONNECTED'
export const WS_CONNECT = 'WS_CONNECT'
export const WS_DISCONNECT = 'WS_DISCONNECT

我的应用操作(操作创建者)

import * as types from './actionsTypes'
export function wsConnecting() {
  return {
    type: types.WS_CONNECTING
  }
}

export function wsConnected() {
  return {
    type: types.WS_CONNECTED
  }
}

export function wsDisconnected(reason = "No reason") {
  return {
    type: types.WS_DISCONNECTED,
    reason
  }
}

export function wsConnect(url) {
  return {
    type: types.WS_CONNECT,
    url: url
  }
}

还有我的减速机

    import * as types from '../actions/actionsTypes'

    function appReducers(state = [], action) {
      switch (action.type) {
        case types.WS_CONNECTING:      
          return Object.assign({}, state, { status: types.WS_CONNECTING });
        case types.WS_CONNECTED:      
          return Object.assign({}, state, { status: types.WS_CONNECTED });
        case types.WS_DISCONNECTED:      
          return Object.assign({}, state, { status: types.WS_DISCONNECTED });
        default:
          return state
      }
    }

    export default appReducers

我尝试安装和导入库 websocket-as-promised (https://www.npmjs.com/package/websocket-as-promised),然后我只替换了我的 websocket 中的这段代码:

socket = new WebSocket(action.url);

**通过这个但它不起作用**

socket = new WebSocketAsPromised(action.url);

【问题讨论】:

    标签: javascript reactjs websocket redux react-redux


    【解决方案1】:

    谢谢,我找到了我想要的解决方案。 我为那些想要 redux 承诺的 websocket 的人分享我的自定义 websocket:

    import actions from './actions'
    import WebSocketAsPromised from 'websocket-as-promised';
    
    const socketMiddleware = (function() {
        var socket = null;
    
        const onOpen = (ws, store, token) => {
            //Send a handshake, or authenticate with remote end
    
            //Tell the store we're connected
            store.dispatch(actions.connected());
        }
    
        const onClose = (ws, store) => {
            //Tell the store we've disconnected
            store.dispatch(actions.disconnected());
        }
    
        const onMessage = (msg, store) => {
            //Parse the JSON message received on the websocket
            var msg = msg;
            switch (msg.type) {
                case "CHAT_MESSAGE":
                    //Dispatch an action that adds the received message to our state
                    store.dispatch(actions.messageReceived(msg));
                    break;
                default:
                    console.log("Received unknown message type: '" + msg.type + "'");
                    break;
            }
        }
    
        return store => next => action => {
            switch (action.type) {
    
                //The user wants us to connect
                case 'CONNECT':
                    //Start a new connection to the server
                    if (socket != null) {
                        socket.close();
                    }
                    //Send an action that shows a "connecting..." status for now
                    store.dispatch(actions.connecting());
    
                    //Attempt to connect (we could send a 'failed' action on error)
                    socket = new WebSocketAsPromised(action.url);
                    socket.onMessage.addListener((data, jsonData) => onMessage(jsonData, store))
                    socket.onClose.addListener(() => onClose(socket, store))
                    socket.open()
                          .then(() => {onOpen(socket, store, action.token)})
                    break;
    
                    //The user wants us to disconnect
                case 'DISCONNECT':
                    if (socket != null) {
                        socket.close();
                    }
                    socket = null;
    
                    //Set our state to disconnected
                    store.dispatch(actions.disconnected());
                    break;
    
                    //Send the 'SEND_MESSAGE' action down the websocket to the server
                case 'SEND_CHAT_MESSAGE':
                    socket.send(JSON.stringify(action));
                    break;
    
                    //This action is irrelevant to us, pass it on to the next middleware
                default:
                    return next(action);
            }
        }
    
    })();
    
    export default socketMiddleware

    【讨论】:

      【解决方案2】:

      您还可以查看redux-websocket-bridge,它可以将所有 Web Socket 消息展开到您的 Redux 存储中,并将所有 Redux 操作中继到 Web Socket。它可以为您节省一些处理 CHAT_MESSAGESEND_CHAT_MESSAGE 的工作。

      除了展开/中继操作之外,它还通过 Redux 操作公开 Web Socket 事件。

      【讨论】:

        猜你喜欢
        • 2018-01-08
        • 1970-01-01
        • 1970-01-01
        • 2016-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多