Search code examples
reactjssignalr

SignalR Send Message On Connection in React


I have a React application that has a SignalR connection. In the useEffect functions the connection is built and then it is connected to the server. Once that connection is made the client sends a message to the server in order to join a group to receive messages. I have the withAutomaticReconnect method on the connection. The problem is if there is a connection disruption and it does reconnect, that works fine. However, my method that then sends a message to the server on initial connection doesn't run again, so even though the client - server connection is reestablished, the message method is not sent again. My question is, how can I setup the connection to automatically send a message to the server upon connection?

Here is the code:

  const [connection, setConnection] = useState(null);

 // Create connection with server
  useEffect(() => {
    const hubConnection = new signalR.HubConnectionBuilder()
      .withUrl(`${process.env.REACT_APP_API_URL}/hubs/hub`, {
        withCredentials: false,
        accessTokenFactory: () => {
          // Get and return the access token.
          // This function can return a JavaScript Promise if asynchronous
          // logic is required to retrieve the access token.

          return getSessionAccessToken();
        },
      })
      .withAutomaticReconnect()
      .build();

    setConnection(hubConnection);
    const startConnection = async () => {
      try {
        await hubConnection.start();
      } catch (error) {
        const toastInfo = {
          description: HUB_CONNECTION_ERROR_MESSAGE,
          type: TOAST_TYPES.error,
        };
        dispatch(addToast(toastInfo));
      }
      try {
      // ======================== This function below needs to run every initial connection and every reconnection.  Currently this isn't run on reconnection, which is expected but I am not sure how to add that to the hubConnection itself ========================
        await hubConnection.send(HUB_CONNECTION_TYPES.ADD_USER_TO_GROUP, {
          groupId: groupId,
        });
      } catch (error) {
        const toastInfo = {
          description: HUB_CONNECTION_ERROR_MESSAGE,
          type: TOAST_TYPES.error,
        };
        dispatch(addToast(toastInfo));
      }
    };
    startConnection();
  }, [groupId, dispatch]);

  // Functions to be run based on connection server actions
  useEffect(() => {
    if (connection) {
      connection.on(
        HUB_CONNECTION_TYPES.RECEIVING_MESSAGE,
        (message) => {
          dispatch(function(message.receivingMessage));
        }
      );
    }

    // Returns in useEffect functions run when the component dismounts (e.g. leaving the page)
    return async () => {
      if (connection) {
        await connection.send(HUB_CONNECTION_TYPES.REMOVE_USER_FROM_GROUP, {
          groupId: groupId,
        });
        connection.stop();
      }
    };
  }, [connection, groupId, dispatch]);

Solution

  • I figured out the answer to this scenario. There is a method on the connection that can be called if a reconnect occurs: hubConnection.onreconnected(callback function)