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