栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用socket.io的React-Redux和Websockets

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用socket.io的React-Redux和Websockets

Spoiler: 我目前正在开发一个开源聊天应用程序。

通过将操作与中间件分离,甚至将套接字客户端与中间件分离,您可以做得更好。因此,结果如下:

  • 类型 ->每个请求的REQUEST,SUCCESS,FAILURE类型(不是必需的)。
  • 减速器 ->存储不同状态
  • 动作 ->发送动作以连接/断开连接/发出/监听。
  • 中间件 ->处理您的操作,并将当前操作传递或不传递给套接字客户端
  • 客户端 ->套接字客户端(socket.io)。

下面的代码取材于正在开发的真实应用程序(有时需要进行少量编辑),它们足以应付大多数情况,但某些东西(例如SocketClient)可能未必100%完整。

动作

您希望动作尽可能简单,因为它们通常是重复的工作,并且您最终可能会拥有很多动作。

    export function send(chatId, content) {      const message = { chatId, content };      return {        type: 'socket',        types: [SEND, SEND_SUCCESS, SEND_FAIL],        promise: (socket) => socket.emit('SendMessage', message),      }    }

注意,套接字是一个参数化函数,通过这种方式,我们可以在整个应用程序中共享相同的套接字实例,而不必担心任何导入(稍后将说明如何执行此操作)。

中间件(socketMiddleware.js):

我们将使用与erikras / react-redux-universal-hot-
example示例
类似的策略,但是将它用于套接字而不是AJAX。

我们的套接字中间件将仅负责处理套接字请求。

中间件将操作传递到套接字客户端,并调度:

  • REQUEST(操作
    types[0]
    ):正在请求(
    action.type
    发送到减速器)。
  • SUCCESS(操作
    types[1]
    ):在请求成功时(
    action.type
    服务器响应
    action.result
    发送到reducer)。
  • FAILURE(操作
    types[2]
    ):根据请求失败(
    action.type
    以及服务器响应
    action.error
    发送到减速器)。
    export default function socketMiddleware(socket) {      // Socket param is the client. We'll show how to set this up later.      return ({dispatch, getState}) => next => action => {        if (typeof action === 'function') {          return action(dispatch, getState);        }                const { promise, type, types, ...rest } = action;        if (type !== 'socket' || !promise) {          // Move on! Not a socket request or a badly formed one.          return next(action);        }        const [REQUEST, SUCCESS, FAILURE] = types;        next({...rest, type: REQUEST});        return promise(socket)          .then((result) => { return next({...rest, result, type: SUCCESS });          })          .catch((error) => { return next({...rest, error, type: FAILURE });          })      };    }

SocketClient.js

唯一可以加载和管理socket.io-client的程序。

[可选](请参阅代码下面的1)。
关于so​​cket.io的一个非常有趣的功能是您可以得到消息确认,这是在执行HTTP请求时的典型答复。我们可以使用它们来验证每个请求是否正确。请注意,为了利用此功能,服务器socket.io命令还必须具有此最新的确认参数。

    import io from 'socket.io-client';    // Example conf. You can move this to your config file.    const host = 'http://localhost:3000';    const socketPath = '/api/socket.io';    export default class socketAPI {      socket;      connect() {        this.socket = io.connect(host, { path: socketPath });        return new Promise((resolve, reject) => {          this.socket.on('connect', () => resolve());          this.socket.on('connect_error', (error) => reject(error));        });      }      disconnect() {        return new Promise((resolve) => {          this.socket.disconnect(() => { this.socket = null; resolve();          });        });      }      emit(event, data) {        return new Promise((resolve, reject) => {          if (!this.socket) return reject('No socket connection.');          return this.socket.emit(event, data, (response) => { // Response is the optional callback that you can use with socket.io in every request. See 1 above. if (response.error) {   console.error(response.error);   return reject(response.error); } return resolve();          });        });      }      on(event, fun) {        // No promise is needed here, but we're expecting one in the middleware.        return new Promise((resolve, reject) => {          if (!this.socket) return reject('No socket connection.');          this.socket.on(event, fun);          resolve();        });      }    }

app.js

在应用启动时,我们初始化

SocketClient
并将其传递到商店配置。

const socketClient = new SocketClient();const store = configureStore(initialState, socketClient, apiClient);

configureStore.js

我们将

socketMiddleware
带有新初始化的的添加
SocketClient
到商店中间件(还记得我们告诉您的参数,我们稍后会解释吗?)。

    export default function configureStore(initialState, socketClient, apiClient) {    const loggerMiddleware = createLogger();    const middleware = [      ...      socketMiddleware(socketClient),      ...    ];

[没什么特别的]动作类型常量

没什么特别的=您通常会做什么。

const SEND = 'redux/message/SEND';const SEND_SUCCESS = 'redux/message/SEND_SUCCESS';const SEND_FAIL = 'redux/message/SEND_FAIL';

[没什么特别的]减速机

    export default function reducer(state = {}, action = {}) {      switch(action.type) {        case SEND: {          return { ...state, isSending: true,          };        }        default: {          return state;        }      }    }

它可能看起来像很多工作,但是一旦完成设置,就值得了。您的相关代码将更易于阅读,调试,并且不易出错。

PS: 您也可以通过AJAX API调用遵循此策略。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/436755.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号