在 Redux 中间件中调用 SignalR 连接上的方法向服务器发送消息

Invoking a method on SignalR connection in Redux middleware to send message to server

我在 Redux 中使用中间件连接到我的 signalR 集线器,它运行良好,我可以毫无问题地接收消息。

现在我已经到了要调用服务器上的方法以“加入群组”的地步。

最好的方法是什么?我有一个连接,因此在操作“JOIN_GROUP”上重新创建连接似乎违反直觉。

我想我读 xxx 的时候可能会有所作为,所以我可以链接

import {
JsonHubProtocol,
  HttpTransportType,
  HubConnectionBuilder,
  LogLevel,
} from '@microsoft/signalr';

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

const signalRMiddleware =
  ({ dispatch, getState }) =>
  (next) =>
  async (action) => {
    let connection;
    // register signalR after the user logged in
    if (action.type === actionTypes.USER_SIGNED_IN) {
      const connectionHub =
        window.globalConfig?.hubUrl || process.env.REACT_APP_HUB_URL;

      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.Critical,
        accessTokenFactory: () => action.user.access_token,
      };

      // create the connection instance
      connection = new HubConnectionBuilder()
        .withUrl(`${connectionHub}/hub/notificationhub`, options)
        .withHubProtocol(protocol)
        .build();

      //add "on" events here...

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

      startSignalRConnection(connection);
    } else if (action.type === actionTypes.JOIN_GROUP) {
      connection.invoke('JoinGroup', action.groupName);
    }

    return next(action);
  };
export const joinGroup = (groupName) => (dispatch, getState, invoke) => {
  invoke('JoinGroup', groupName);
};
export default signalRMiddleware;

当我发送“JOIN_GROUP”动作时,连接未定义:

} else if (action.type === actionTypes.JOIN_GROUP) {
          // connection is undefined
          connection.invoke('JoinGroup', action.groupName);
}

我确实在某处读到过有关能够将调用方法从连接传递到另一个方法的信息。因此:

export const joinGroup = (groupName) => (dispatch, getState, invoke) => {
      invoke('JoinGroup', groupName);
    };

但我不知道如何使用它,也不知道如何填充调用以便在我的组件中使用它。

如有任何帮助,我们将不胜感激。

亚历克斯

设法解决了。最后这是一个非常小的调整,因为 let 连接需要在初始 (next)

之前
import {
  JsonHubProtocol,
  HttpTransportType,
  HubConnectionBuilder,
  LogLevel,
} from '@microsoft/signalr';

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

const signalRMiddleware = ({ dispatch, getState }) => {
  let connection;
  return (next) => async (action) => {
    // register signalR after the user logged in
    if (action.type === actionTypes.USER_SIGNED_IN) {
      const connectionHub =
        window.globalConfig?.hubUrl || process.env.REACT_APP_HUB_URL;

      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.Critical,
        accessTokenFactory: () => action.user.access_token,
      };

      // create the connection instance
      connection = new HubConnectionBuilder()
        .withUrl(`${connectionHub}/hub/notificationhub`, options)
        .withHubProtocol(protocol)
        .build();

      //add "on" events here...

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

      startSignalRConnection(connection);
    } else if (action.type === actionTypes.JOIN_GROUP) {
      connection.invoke('JoinGroup', action.groupName);
      return;
    }
    return next(action);
  };
};
export default signalRMiddleware;