robtaussig / react-use-websocket

React Hook for WebSocket communication
MIT License
1.63k stars 135 forks source link

Handle ping/pong #70

Closed jleei closed 3 years ago

jleei commented 3 years ago

The server sends a PING message to the client, which then need reply with PONG. Is there any good way to deal with this?

robtaussig commented 3 years ago

Hi @brioapp,

If you are using the useSocketIO plugin (you can import it as a named export from 'react-use-websocket'), then the ping-pong behavior required for socketIO should be handled for you. If you are using the default hook, then I'd recommend something like:

import React, { useEffect } from 'react';
import useWebSocket from 'react-use-websocket';

const PingPongDemonstrationComponent = () => {
  const {
    sendMessage,
    lastMessage,
    readyState,
  } = useWebSocket(/*url*/);

  useEffect(() => {
    if (lastMessage && lastMessage.data === 'PING') {
      sendMessage('PONG');
    }
  }, [lastMessage, sendMessage]) //sendMessage is stable and thus doesn't *need* to be a dependency here, but for peace of mind/lint rules it doesn't hurt to add it

  return //
}
MarcelRobitaille commented 3 years ago

This assumes that the ping / pong is handled with sendMessage('PING') and sendMessage('PONG'), but what happens if I use node ws on my server with client.ping() and client.on('pong')? I don't even see these ping messages in the frontend and ws doesn't recognize sendMessage('PONG') in client.on('pong').

jm42 commented 11 months ago

Same rationale as Marcel, is this supported by this library?

levino commented 8 months ago

Does it really make sense to trigger a rerender of the component for this message? Would it not be better to handle this in the onMessage hook in the options given to useWebsocket?

robtaussig commented 8 months ago

@levino in hindsight, I agree with you — no reason to have done this via an effect. Though it would have also required using the filter option if the goal was to prevent a component rerender. Since this thread has been closed, there is a new option to handle ping/pong automatically.

levino commented 8 months ago

Ah! That is what I came here looking for. Could you give me the reference or documentation on that? I am wondering whether or not I have to implement that myself or if the automatic implementation handles my use case correctly...

robtaussig commented 8 months ago

@levino Here you go!

levino commented 8 months ago

I saw that. However I need to send pong when the server sends ping. And I need to send the ping's payload along with the pong. Is that handled too?

robtaussig commented 8 months ago

Ahh, in that case you will need to do a little manual setup. I’d start with the example here, and in your update heartbeat function, invoke sendMessage as needed.

levino commented 8 months ago

Thank you! It is a weird set up, is it not? The server asking the clients if they are still there? Also very easy to test: Just wait 13 minutes and 20 seconds and see if the connection is still alive... I guess your library will by then have reestablished the connection anyhow so...

robtaussig commented 8 months ago

I agree — there are nuances between heartbeat vs. ping/pong, and I can see how the two are conflated in our documentation example. I plan on doing an official ping/pong in the future, but welcome PRs by anyone that wants it supported sooner!