Skip to content

Event-Source onMessage is not triggering for both android and iOS platform. #70

Open

Description

@amit13091992

I have a project in react native CLI.

  "react": "^18.2.0",
  "react-native": "^0.73.9",
  "react-native-sse": "^1.2.1"

Usage:

   const createVitalsEventSource = async () => {
       const url = `EVENT_SOURCE_WEB_SOCKET_URL`;

       const eventSource = new EventSource(url, {
           headers: {
               Authorization: `Bearer ${token}`,
           },
           withCredentials: true,
           lineEndingCharacter: '\n',
           debug: true,
           pollingInterval: 0,
           timeoutBeforeConnection: 1000,
       });
       eventSourceRef.current = eventSource;

       const listener: EventSourceListener = (event: any) => {
           if (event.type === "open") {
               console.log('openSSEConnection');
           } else if (event.type === "message") {
               console.log('getting event message');
           } else if (event.type === "error") {
               console.log('getting event error');
           } else if (event.type === "close") {
               console.log('closing event source');
           }
       };
       eventSource.addEventListener("open", listener);
       eventSource.addEventListener("message", listener);
       eventSource.addEventListener("error", listener);
       eventSource.addEventListener("close", listener);
   };

It was working around a week back but suddenly stopped working.
Note: In Android, it is not at all working so I needed to use another library "react-native-oksse"

Activity

  1. changed the title [-]Event-Source onMessage is not working for both android and iOS platform.[/-] [+]Event-Source onMessage is not triggering for both android and iOS platform.[/+] on Nov 19, 2024
  2. EmilJunker commented on Nov 19, 2024

    @EmilJunker
    Contributor

    To get SSE working on Android with React Native versions prior to 0.74, you have to disable the Flipper plugin. See https://stackoverflow.com/questions/69235694/react-native-cant-connect-to-sse-in-android/69235695#answer-69235695

    As long as Flipper is enabled, SSE won't work in debug builds on Android.

    If you run into more issues, please share the logs with us so we can see what is going on.

  3. amit13091992 commented on Nov 19, 2024

    @amit13091992
    Author

    To get SSE working on Android with React Native versions prior to 0.74, you have to disable the Flipper plugin. See https://stackoverflow.com/questions/69235694/react-native-cant-connect-to-sse-in-android/69235695#answer-69235695

    As long as Flipper is enabled, SSE won't work in debug builds on Android.

    If you run into more issues, please share the logs with us so we can see what is going on.

    Okay but should work in iOS thought right ?

  4. EmilJunker commented on Nov 19, 2024

    @EmilJunker
    Contributor

    Okay but should work in iOS thought right ?

    Yes, but we can only help you if you show us the logs.

  5. amit13091992 commented on Nov 20, 2024

    @amit13091992
    Author

    @EmilJunker
    Please find below logs that I receive when I start connecting using Event source:

     DEBUG  [EventSource] Will open new connection in 1000 ms.
     DEBUG  [EventSource][onreadystatechange] ReadyState: HEADERS_RECEIVED(2), status: 200
     DEBUG  [EventSource][onreadystatechange] ReadyState: LOADING(3), status: 200
     LOG  Open SSE connection.
     DEBUG  [EventSource][onreadystatechange][OPEN] Connection opened.
     DEBUG  [EventSource][onreadystatechange] ReadyState: LOADING(3), status: 200
     DEBUG  [EventSource][onreadystatechange] ReadyState: LOADING(3), status: 200
     DEBUG  [EventSource][onreadystatechange] ReadyState: LOADING(3), status: 200
    
    

    After waiting for 5 to 10 minutes, it remains the same. I have already attached a code reference. If any other additional information is needed please let me know.

  6. EmilJunker commented on Nov 20, 2024

    @EmilJunker
    Contributor

    If everything was working correctly, there should be a lot more log messages of the kind

     DEBUG  [EventSource][onreadystatechange] ReadyState: LOADING(3), status: 200
    

    Are you sure that the SSE endpoint you connect to is working properly? I find it suspicious that a week ago everything was working fine and it suddenly stopped. This sounds like a backend issue to me.

  7. amit13091992 commented on Nov 20, 2024

    @amit13091992
    Author

    t to is working properly? I find it suspicious that a week ago everything was working fine and it suddenly stopped. This sounds like a backend issue to me.

    I have checked from backend side, after confirming i.e. nothing changed from backend, I checked on the app side.

    @EmilJunker Could you please help me out on this issue, as suddenly It stopped working, it has become a blocker :(

  8. EmilJunker commented on Nov 20, 2024

    @EmilJunker
    Contributor

    Does your app work if you connect to this SSE test endpoint instead of the actual backend?
    https://fetch-eventstream.glitch.me/sse

  9. amit13091992 commented on Nov 20, 2024

    @amit13091992
    Author

    Does your app work if you connect to this SSE test endpoint instead of the actual backend? https://fetch-eventstream.glitch.me/sse

        const testingEventSource = async () => {
        const url = `https://fetch-eventstream.glitch.me/sse`;
        const eventSource = new EventSource(url, {
        });
        eventSourceRef.current = eventSource;
    
        const listener: EventSourceListener = (event: any) => {
            console.log(t('calling event source ' + JSON.stringify(event)));
            if (event.type === "open") {
                console.log('openSSEConnection');
            } else if (event.type === "message") {
            } else if (event.type === "error") {
                console.error('connectionError', event.message);
            } else if (event.type === "close") {
                console.error("Error: ", event.message, event.error);
            }
        };
    
        eventSource.addEventListener("open", listener);
        eventSource.addEventListener("message", listener);
        eventSource.addEventListener("error", listener);
        eventSource.addEventListener("close", listener);
    };
    

    LOGS:
    LOG calling event source {"type":"open"}
    LOG Open SSE connection.

    After this, nothing comes in logs. @EmilJunker

  10. EmilJunker commented on Nov 20, 2024

    @EmilJunker
    Contributor

    Sorry, I forgot to tell you to add an event listener for the "increment" event like so:

    eventSource.addEventListener("increment", (event) => {
      console.log(event.data);
    });
    
  11. amit13091992 commented on Nov 20, 2024

    @amit13091992
    Author
    const testingEventSource = async () => {
            const url = `https://fetch-eventstream.glitch.me/sse`;
    
            const eventSource = new EventSource(url, {
            });
            eventSourceRef.current = eventSource;
    
            const listener: EventSourceListener = (event: any) => {
                console.log(t('calling event source ' + JSON.stringify(event)));
                if (event.type === "open") {
                    console.log('openSSEConnection');
                } else if (event.type === "message") {
                    console.log('openSSEConnection message: ' + JSON.stringify(event.data));
                } else if (event.type === "increment") {
                    console.log('openSSEConnection increment: ' + JSON.stringify(event.data));
                } else if (event.type === "error") {
                    console.error('connectionError', event.message);
                } else if (event.type === "close") {
                    console.error("Error: ", event.message, event.error);
                }
            };
            eventSource.addEventListener("open", listener);
            eventSource.addEventListener("message", listener);
            eventSource.addEventListener("increment", listener);
            eventSource.addEventListener("error", listener);
            eventSource.addEventListener("close", listener);
        };
    

    Updated Library code like below:

    ```
        export type BuiltInEventType = 'open' | 'message' | 'error' | 'close' | 'increment';
        export type EventType<E extends string = never> = E | BuiltInEventType;
        
        export interface MessageEvent {
          type: 'message';
          data: string | null;
          lastEventId: string | null;
          url: string;
        }
    
        export interface IncrementEvent {
          type: 'increment';
          data: string | null;
          lastEventId: string | null;
          url: string;
        }
        
        export interface OpenEvent {
          type: 'open';
        }
        
        export interface CloseEvent {
          type: 'close';
        }
        
        export interface TimeoutEvent {
          type: 'timeout';
        }
        
        export interface ErrorEvent {
          type: 'error';
          message: string;
          xhrState: number;
          xhrStatus: number;
        }
        
        export interface CustomEvent<E extends string> {
          type: E;
          data: string | null;
          lastEventId: string | null;
          url: string;
        }
        
        export interface ExceptionEvent {
          type: 'exception';
          message: string;
          error: Error;
        }
        
        export interface EventSourceOptions {
          method?: string;
          timeout?: number;
          timeoutBeforeConnection?: number;
          withCredentials?: boolean;
          headers?: Record<string, any>;
          body?: any;
          debug?: boolean;
          pollingInterval?: number;
          lineEndingCharacter?: string;
        }
        
        type BuiltInEventMap = {
          'message': MessageEvent,
          'open': OpenEvent,
          'increment': IncrementEvent,
          'close': CloseEvent,
          'error': ErrorEvent | TimeoutEvent | ExceptionEvent,
        };
        
        export type EventSourceEvent<E extends T, T extends string = any> = E extends BuiltInEventType ? BuiltInEventMap[E] : CustomEvent<E>;
        export type EventSourceListener<E extends string = never, T extends EventType<E> = EventType<E>> = (
          event: EventSourceEvent<T>
        ) => void;
        
        declare class EventSource<E extends string = never> {
          constructor(url: URL | string, options?: EventSourceOptions);
          open(): void;
          close(): void;
          addEventListener<T extends EventType<E>>(type: T, listener: EventSourceListener<E, T>): void;
          removeEventListener<T extends EventType<E>>(type: T, listener: EventSourceListener<E, T>): void;
          removeAllEventListeners<T extends EventType<E>>(type?: T): void;
          dispatch<T extends EventType<E>>(type: T, data: EventSourceEvent<T>): void;
        }
        
        export default EventSource;
    
    
     LOG  calling event source {"type":"open"}
     LOG  openSSEConnection
     LOG  calling event source {"type":"increment","data":"hello from SSE #0","url":"https://fetch-eventstream.glitch.me/sse","lastEventId":"0"}
     LOG  openSSEConnection increment: "hello from SSE #0"
     LOG  calling event source {"type":"increment","data":"hello from SSE #1","url":"https://fetch-eventstream.glitch.me/sse","lastEventId":"1"}
     LOG  openSSEConnection increment: "hello from SSE #1"
     LOG  calling event source {"type":"increment","data":"hello from SSE #2","url":"https://fetch-eventstream.glitch.me/sse","lastEventId":"2"}
     LOG  openSSEConnection increment: "hello from SSE #2"
     LOG  calling event source {"type":"increment","data":"hello from SSE #3","url":"https://fetch-eventstream.glitch.me/sse","lastEventId":"3"}
     LOG  openSSEConnection increment: "hello from SSE #3"
     LOG  calling event source {"type":"increment","data":"hello from SSE #4","url":"https://fetch-eventstream.glitch.me/sse","lastEventId":"4"}
    
  12. EmilJunker commented on Nov 20, 2024

    @EmilJunker
    Contributor

    Good, so the example from glitch.me works.

    I don't know yet why it's not working with your other backend, though. I think it might be related to the lineEndingCharacter option that you specify. Have you tried it without that option?

    By the way, you don't need to edit the library code to add custom events (like "increment"). You can do that with a type parameter like so:

    type CustomEvents = 'increment' | 'decrement';
    
    const eventSource = new EventSource<CustomEvents>(url, {});
    
    const listener: EventSourceListener<CustomEvents> = (event) => {
        ...
    };
    
    eventSource.addEventListener('increment', listener);
  13. amit13091992 commented on Nov 20, 2024

    @amit13091992
    Author

    @EmilJunker with my implementation, I am attaching token as well in the header i.e. the change which I have in my implementation. I have added latest change you suggested for the increment one. But still the issue persists.
    Logic:

     const callEventSourceAPI = async () => {
         const url = `MY_URL`;
    
         const eventSource = new EventSource(url, {
             headers: {
                 Authorization: `Bearer ${token}`,
             },
             withCredentials: true,
             lineEndingCharacter: '\n',
             debug: true,
             pollingInterval: 0,
             timeoutBeforeConnection: 1000,
         });
         eventSourceRef.current = eventSource;
    
         const listener: EventSourceListener = (event: any) => {
             console.log(t('calling event source ' + JSON.stringify(event)));
             if (event.type === "open") {
                 console.log('openSSEConnection');
             } else if (event.type === "message") {
                 console.log('openSSEConnection message: ' + JSON.stringify(event.data));
             } else if (event.type === "increment") {
                 console.log('openSSEConnection increment: ' + JSON.stringify(event.data));
             } else if (event.type === "error") {
                 console.error('connectionError', event.message);
             } else if (event.type === "close") {
                 console.error("Error: ", event.message, event.error);
             }
         };
         eventSource.addEventListener("open", listener);
         eventSource.addEventListener("message", listener);
         eventSource.addEventListener("increment", listener);
         eventSource.addEventListener("error", listener);
         eventSource.addEventListener("close", listener);
     };
    
    

    LOGS:

           DEBUG  [EventSource] Will open new connection in 1000 ms.
           DEBUG  [EventSource] Will open new connection in 1000 ms.
           DEBUG  [EventSource][onreadystatechange] ReadyState: HEADERS_RECEIVED(2), status: 200
           DEBUG  [EventSource][onreadystatechange] ReadyState: LOADING(3), status: 200
           LOG  calling event source {"type":"open"}
           LOG  openSSEConnection
           DEBUG  [EventSource][onreadystatechange][OPEN] Connection opened.
           DEBUG  [EventSource][onreadystatechange] ReadyState: LOADING(3), status: 200
           DEBUG  [EventSource][onreadystatechange] ReadyState: LOADING(3), status: 200
           DEBUG  [EventSource][onreadystatechange] ReadyState: LOADING(3), status: 200
           DEBUG  [EventSource][onreadystatechange] ReadyState: LOADING(3), status: 200
    
  14. amit13091992 commented on Nov 20, 2024

    @amit13091992
    Author

    I think it might be related to the lineEndingCharacter option that you specify. Have you tried it without that option?

    tried this but didn't help. @EmilJunker

  15. EmilJunker commented on Nov 20, 2024

    @EmilJunker
    Contributor

    @amit13091992 Sorry, I'm out of ideas. I don't see anything wrong with your code. I still think it must be a backend issue. I'm afraid you're on your own - good luck!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions