Reactjs 在哪里以及如何在redux中添加信号器?

Reactjs 在哪里以及如何在redux中添加信号器?,reactjs,redux,signalr,Reactjs,Redux,Signalr,我正在创建一个react应用程序,它实现了signar,到目前为止,我已经在组件中找到了我需要的连接和所有侦听器。问题是我在Redux中有动作创建者,他们只是发出请求并获得响应,以便调用我的服务器并将数据发送给所有其他客户端。一旦服务器向所有客户端发出事件,我的一个侦听器就会获取数据并调用一个动作创建者,该动作创建者只发送一个动作来刷新我的redux状态 我觉得我没有以正确的方式使用action creator,因为我有一个action creator,它只是发出请求并得到返回的响应,并且没有改

我正在创建一个react应用程序,它实现了signar,到目前为止,我已经在组件中找到了我需要的连接和所有侦听器。问题是我在Redux中有动作创建者,他们只是发出请求并获得响应,以便调用我的服务器并将数据发送给所有其他客户端。一旦服务器向所有客户端发出事件,我的一个侦听器就会获取数据并调用一个动作创建者,该动作创建者只发送一个动作来刷新我的redux状态

我觉得我没有以正确的方式使用action creator,因为我有一个action creator,它只是发出请求并得到返回的响应,并且没有改变状态

如果存储中有套接字连接,我只需调用一个动作创建者,发出或侦听套接字事件的逻辑将位于其他位置

这是我的组件

/--component.js---
状态={
连接:空,
};
异步组件didmount(){
//处理任何网络异常并显示错误消息
试一试{
等待此消息。setupConnection();
}捕获(错误){
this.showNetworkError(`哎呀,你的网络连接有错误。请重新加载页面`);
}
设置连接=()=>{
设{connection}=this.state;
这是我的国家({
连接:(connection=new-HubConnectionBuilder().withUrl(HUB\u URL.build()),
});
/**
*通过WebSocket从服务器调用的侦听器
*/
connection.on('InsertTodo',data=>{
//动作创造者
this.props.add(数据);
});
connection.on('UpdateTodo',data=>{
//动作创造者
此.props.update(数据);
});
}
createTodo=异步todo=>{
const{connection}=this.state;
//动作创造者
const createdTodo=wait this.props.createTodo(todo);
如果(createdTodo){
//下面的句子调用服务器向所有其他客户端发出/发送todo项
//然后执行setupConnection函数中的侦听器
调用('EmitTodoCreate',createdTodo);
}否则{
//创建待办事项时出现问题
}

}
我认为最好的解决方案是实现Redux中间件。这很简单,您可以使用身份验证来建立连接,并且您可以根据Signal发出的不同消息来分派操作创建者

根据Redux常见问题解答

这是我的自定义中间件,用于建立连接并注册处理程序。请注意,我只希望接收数据,而对发送数据不感兴趣。我使用REST API将数据发送到服务器

import {
  JsonHubProtocol,
  HttpTransportType,
  HubConnectionBuilder,
  LogLevel
} from '@aspnet/signalr'; // version 1.0.4

// action for user authentication and receiving the access_token
import { USER_SIGNED_IN } from '../actions/auth';

const onNotifReceived = res => {
  console.log('****** NOTIFICATION ******', res);
};

const startSignalRConnection = connection => connection.start()
  .then(() => console.info('SignalR Connected'))
  .catch(err => console.error('SignalR Connection Error: ', err));

const signalRMiddleware = ({ getState }) => next => async (action) => {
  // register signalR after the user logged in
  if (action.type === USER_SIGNED_IN) {
    const urlRoot = (window.appConfig || {}).URL_ROOT;
    const connectionHub = `${urlRoot}/api/service/hub`;

    const protocol = new JsonHubProtocol();

    // let transport to fall back to to LongPolling if it needs to
    const transport = HttpTransportType.WebSockets | HttpTransportType.LongPolling;

    const options = {
      transport,
      logMessageContent: true,
      logger: LogLevel.Trace,
      accessTokenFactory: () => action.user.access_token
    };

    // create the connection instance
    const connection = new HubConnectionBuilder()
      .withUrl(connectionHub, options)
      .withHubProtocol(protocol)
      .build();

    // event handlers, you can use these to dispatch actions to update your Redux store
    connection.on('OperationProgress', onNotifReceived);
    connection.on('UploadProgress', onNotifReceived);
    connection.on('DownloadProgress', onNotifReceived);

    // re-establish the connection if connection dropped
    connection.onclose(() => setTimeout(startSignalRConnection(connection), 5000));

    startSignalRConnection(connection);
  }

  return next(action);
};

export default signalRMiddleware;
在我的store.js文件中

import signalRMiddleware from '../middlewares/signalRMiddleware';

...

createStore(rootReducer, {}, composeEnhancers(applyMiddleware(signalRMiddleware)));

当存在多个
connectionHub
(多个hub URL)时该怎么办?@Akhilesh,我想说的是创建多个与其他hub URL的“连接”实例。新的“连接”实例将能够处理这些hub URL上的新事件。