有什么方法可以同时使用react和SignalR。
我尝试了一些例子,但没有成功。
componentDidMount = () => {
const nick = window.prompt('Your name:', 'John');
//const hubConnection = new HubConnection('http://localhost:5000/chat');
//Said deprecated
const hubConnection = new HubConnectionBuilder().withUrl('http://localhost:5000/chat').build();
this.setState({ hubConnection, nick }, () => {
this.state.hubConnection
.start()
.then(() => console.log('Connection started!'))
.catch(err => console.log('Error while establishing connection :('));
this.state.hubConnection.on('sendToAll', (nick, receivedMessage) => {
const text = `${nick}: ${receivedMessage}`;
const messages = this.state.messages.concat([text]);
this.setState({ messages });
});
});
}
这是一个示例,其中提供了HubConnection。但是,当尝试将其设置为状态hubConnection变量时,我是说'hubConnection变量在ReadOnly类型上不存在'
为什么我会收到此错误?
有人可以帮忙吗?
答案 0 :(得分:0)
根据Redux常见问题解答,the right place for websockets and other similar connections is in Redux middleware。在线一些示例描述了如何在组件中添加SignalR,这是一种不好的做法。因为如果您的组件被卸载,则必须重新创建signalR实例。 创建中间件很容易,您可以使用身份验证来建立连接,还可以基于SignalR发出的不同消息来分派操作创建者。
这是我的自定义中间件,用于建立连接并注册处理程序。请注意,我只想接收数据,对发送数据不感兴趣。我使用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)));