react-signalr icon indicating copy to clipboard operation
react-signalr copied to clipboard

Subscription , Invoke Doesn't work with SignalR 8.0 or other issues how the code is written.

Open aukgit opened this issue 6 months ago • 5 comments

Hey @hosseinmd,

Your component connects but doesn't subscribe properly, and the subscription doesn't get the pings.

I have written a SignalR plugin that works completely fine; then, I got your plugin reference to use so that we can remove our code.

Now, when we connect it to the first step then, it doesn't subscribe properly.

Any ping to the subscription doesn't invoke the event.

export const SignalRContext = createSignalRContext();

export default function ContextWrappers({ children }: CommonComponentPropType) {
  const token = getAccessToken();
  const endPoint = 'https://site.app/signalR/hub'; // Signal R v8.0, this endpoint works with the raw connection and my wrapper.

  return (
    <SignalRContext.Provider
      withCredentials={false}
      skipNegotiation={false}
      transport={signalR.HttpTransportType.WebSockets}
      accessTokenFactory={() => token ?? ''}
      headers={{ Authorization: `Bearer ${token}` }}
      connectEnabled={!isEmptyString(token)}
      url={endPoint}
      automaticReconnect
    >
     
                  {children}
           
    </SignalRContext.Provider>
  );
}

Inside another component, before render


  SignalRContext.useSignalREffect(
    eventId,
    (message) => {
      console.log(eventId, message, 'updating - counter', invokedCounter);
      invokedCounter += 1;
      (async () => {
        await refetch?.();
      })();
    },
    [id],
  );

Also, if I try to invoke using your SignalRContext, then it says it's not connected, which means you have not wrapped to after connect, which means connect is happening in a promise, and it was not resolved when I called the SignalRContext.invoke(), if there is a better way to invoke the message please let me know.

Server method, which works with raw connection: image

image

image

const context: Context<T> = {
    connection: null,
    useSignalREffect: null as any, // Assigned after context
    shareConnectionBetweenTab: options?.shareConnectionBetweenTab || false,
    invoke(methodName: string, ...args: any[]): Promise<any> | undefined {
      if (!context.shareConnectionBetweenTab) {
        return context.connection?.invoke(methodName, ...args);
      }

      const SIGNAL_R_RESPONSE = uuid();
      sendWithHermes(
        SIGNAL_R_INVOKE,
        { methodName, args, callbackResponse: SIGNAL_R_RESPONSE },
        context.shareConnectionBetweenTab,
      );
      return new Promise((resolve) => {
        hermes.on(SIGNAL_R_RESPONSE, (data) => {
          resolve(data);
        });
      });
    },

The right way would have been

const listener = this.hubConnection.start();
listener.then(_ => this.hubConnection.invoke(...));

Probably, it is an older version you are using or hermes (message between tabs using localstorage).

Please upgrade your version to the latest one.

Now, this is a severe case. To ping any notification, I must resolve your connection and wait until it is resolved manually. Then, I have to call the invoke every time.

Plus, in your plugin, there needs to be a logger to check which steps are working and what are not, a severe issue regarding enterprise release or production-grade code.

I need to enable the debugging and see what is going on, but here, there is no way to know when you are off; you are doing it on unmount, but what is it really called?

  1. If your component doesn't support v8.0 SignalR, please clearly refer to this.
  2. If you have the bug, please also confirm that. It is important.
  3. How to invoke message for server method using your component?
  4. It is wasting time and resources to investigate your plugin; please help us.
  5. The endpoint (v8 signal) works perfectly with the raw connection (v8 signal r package) and my wrapper. Needs to call as below:
const listener = this.hubConnection.start();
listener.then(_ => this.hubConnection.invoke(...));

I can see that you use hermes to send messages on SingalR using the localstorage; for some reason, it is not working at all. Thus, no message is received.

Please share your solution.

aukgit avatar Jan 29 '24 10:01 aukgit