Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP: periodically send WebSocket heartbeat TEXT frames, a la socket.io #3929

Closed
slandelle opened this issue Aug 6, 2020 · 3 comments
Closed

Comments

@slandelle
Copy link
Member

slandelle commented Aug 6, 2020

socket.io uses a specific heartbeat mechanism based on Data frames (as JavaScript WebSocket API doesn't have access to Ping and Pong frames). See https://socket.io/docs/ "Disconnection detection".
Client will send 2 to server that will respond with 3.
Default period is 25s.

As socket.io is a very standard WebSocket framework, it would be nice to support such mechanism out of the box.

@slandelle slandelle changed the title HTTP: periodically send WebSocket Ping frame HTTP: periodically send WebSocket heartbeat Data frames, a la socket.io Aug 6, 2020
@katerina-stepanova
Copy link

Similar mechanism exists in STOMP protocol as well, but with different heartbeat messages:
Message from server: a["\n"]
Message client responds with: ["\n"]

STOMP docs: https://stomp.github.io/stomp-specification-1.2.html

@slandelle
Copy link
Member Author

@katerina-stepanova thanks for the info

@pschiffe
Copy link
Contributor

Hello @slandelle ,

with Engine.IO 4 release, socket.io reversed heartbeat mechanism. Now server is sending 2 as ping, and expects clients to reply with 3 - https://socket.io/blog/engine-io-4-release/

Our app heavily utilizes socket.io and this change is a nightmare to work with in gatling. Before, we were managing pings by ourselves, but at least we were in control when to send them. Now, I'm sending blind pongs and it kinda works, but not really in complex scenarios.

There are two main issues:

  1. I'm not always listening on websockets, and it's not even possible to do with gatling, since every user is single-threaded / has only serial execution of commands.
  2. I'm not sure if it's possible to listen for 2 kinds of stream messages and react differently to them.

I found https://github.com/gatling/gatling/blob/main/gatling-http-client/src/main/java/io/gatling/http/client/impl/WebSocketHandler.java#L140 and maybe something like this could fix it, but there should by also some kind of socket.io detection as well I guess..

if (frame instanceof TextWebSocketFrame) {
  if (frame.text() == "2") {
    ctx.writeAndFlush(new TextWebSocketFrame("3"));
  } else {
    wsListener.onTextFrame((TextWebSocketFrame) frame);
  }

slandelle pushed a commit that referenced this issue Jun 10, 2021
Some WebSocket implementations require low level automatic replies from
clients to specific messages, for example for heartbeat purposes.

This commit introduces two new WebSocket options: `wsAutoReplyTextFrame`
and `wsAutoReplySocketIo4`.

The `wsAutoReplyTextFrame` is generic, it accepts
`f: PartialFunction[String, String]` as a parameter and allows
configuration of custom reponse for specific message, for example:
`{ case "ping" => "pong" }`

The `wsAutoReplySocketIo4` is utilizing `wsAutoReplyTextFrame` with
pre-configured heartbeat mechanism introduced in Engine.IO v4. It
automatically replies with pong message (`3`) to server ping message
(`2`).
@slandelle slandelle added this to the 3.7.0 milestone Nov 6, 2021
@slandelle slandelle changed the title HTTP: periodically send WebSocket heartbeat Data frames, a la socket.io HTTP: periodically send WebSocket heartbeat TEXT frames, a la socket.io Nov 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants