为 redux 承诺的 Websocket
Posted
技术标签:
【中文标题】为 redux 承诺的 Websocket【英文标题】:Websocket as promised for redux 【发布时间】: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);
【问题讨论】:
【参考方案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_MESSAGE
和 SEND_CHAT_MESSAGE
的工作。
除了展开/中继操作之外,它还通过 Redux 操作公开 Web Socket 事件。
【讨论】:
以上是关于为 redux 承诺的 Websocket的主要内容,如果未能解决你的问题,请参考以下文章
redux thunk - 承诺完成后如何在嵌套数组中调度数据
在 Redux 中的 bindActionCreators 之后无法得到承诺