React和SignalR中的问题,其中SignalR连接未识别

时间:2018-10-10 08:07:53

标签: reactjs typescript signalr

有什么方法可以同时使用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类型上不存在'

为什么我会收到此错误?

有人可以帮忙吗?

1 个答案:

答案 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)));