EventSub WebSocket PONG in browser problems

Hi
I’m trying to migrate from pub-sub to event-sub for the automod functionality with WebSocket on browser side (chromium). (and in the future even the IRC chat that I’m using)

Compared to pub-sub event-sub don’t request a triggered timed PONG event.

But the problem is that after around 2 minutes the WebSocket close itself without reason

CloseEvent {isTrusted: true, wasClean: false, code: 1006, reason: '', type: 'close' .....

after looking to the list of subscribes that I open from the POST api it looks like that the browser don’t send the PONG message.

{id: '0851dd4d-b416', status: 'websocket_failed_ping_pong', .....

here is the code when i open the WebSocket (the commented part was the working pub-sub):

// const ws = new WebSocket('wss://pubsub-edge.twitch.tv')
  const ws = new WebSocket('wss://eventsub.wss.twitch.tv/ws?keepalive_timeout_seconds=30')
  try {

      const listener = (event) => {
          const { data = '{}' } = event;
          const _data = JSON.parse(data);
          console.log(_data);
      }

      // const onOpen = () => {
      //     const topicString = `automod-queue.${tokenUserId}.${broadcasterId}`;
      //     heartbeatHandle = setInterval(() => heartbeat(ws), 10000);
      //     ws.send(JSON.stringify({
      //         "type": "LISTEN",
      //         "data": {
      //             "topics": [topicString],
      //             "auth_token": twitchOAuthToken
      //         }
      //     }));
      // };

      ws.addEventListener('message', listener)
      // ws.addEventListener('open', onOpen)
      ws.addEventListener("close", (event) => {
          console.log(event);
          // clearInterval(heartbeatHandle);
      });
      ws.addEventListener("error", (event) => {
          console.log(event);
          // clearInterval(heartbeatHandle);
      });
  }

and subscription post in react are ok and subscribe correctly to the WebSocket

const body = {
  "type": "automod.message.hold",
  "version": "1",
  "condition": {
    "broadcaster_user_id": broadcasterId,
    "moderator_user_id": tokenUserId,
  },
  "transport": {
    "method": "websocket",
    "session_id": id,
  }
}
query: ({ body = {} }) => ({
    url: 'eventsub/subscriptions',
    method: 'POST',
    body,
}),

there is some way to respond at the PING browser side? or I will need to reopen the WebSocket in case of close event?

As the undlying websocket library will do that for you

Then you are losing the connection?

The underlying websocket library will handle ping/pong as it’s part of the specification

PubSub being websocket-y will also do underlying ping/pong but you also have to ping/pong as distinct messages.

EventSub doesn’t need distinct messages

If this is all you are doing then you are not creating subscriptions? But your earlier log shows you are.

This code is incomplete

Can try cross referenceing what you are doing with an example such as EventSub WebSockets Chat edition with Implicit Auth Example the topic/type’s used won’t matter

The only difference here is I don’t change keepalive_timeout_seconds from the service default but that only changes how often keepalive messages are sent and not related to ping/pong.

yes I’m losing connection, but on listener I don’t see any ping event, I have evidence only on the close event that something goes wrong.

yes I’m doing subscription with react:

const body = {
  "type": "automod.message.hold",
  "version": "1",
  "condition": {
    "broadcaster_user_id": broadcasterId,
    "moderator_user_id": tokenUserId,
  },
  "transport": {
    "method": "websocket",
    "session_id": id,
  }
}
.....
query: ({ body = {} }) => ({
    url: 'eventsub/subscriptions',
    method: 'POST',
    body,
}),

on the specification said that the browser will handle de PONG event but it’s not happening in chromium browser (actually I’m using google Chrome but than I will traslate to chromium base browser).

i will lookout if it can be a react problem handling the socket state.

Those are not normally “loggable” as it’s hidden in the library/underlying specification

:+1: just wanted to check.

Why are you doing this?

This might be useing something non standardy.

(Just trying to understand the use case)

Probably yes, if it’s being messed with between (re)renders by react.

I wanted to create an electron app that is based on chromium, and I have already implemented a plain js app for it, and in the process to re modernize it and make it more maintainable and verify memory performance I’m rebuilding it in react redux, but seems the WebSocket is a big question for the implementation, probably, looking at your example, it’s him that is giving problems

In that scenario I would make the electron main process do the websocket connection

Not the renderer process.

And then on an incoming event into the main process via context bridge push events to the rendered process as needed