0

I'm playing around with vertx and vertx-web. I have a simple endpoint that produces a chunked response by endlessly printing "hello" once a second.

How do I detect when the client disconnects? Vertx doesn't seem to throw an exception when attempting to write to a disconnected client, and routingContext.response().closed() keeps returning false long after the client is gone.

Here's a minimal example, I'm using curl as the client:

public static void main(String[] args) {
    Vertx vertx = Vertx.vertx();
    HttpServer server = vertx.createHttpServer();
    Router router = Router.router(vertx);
    router.route("/hello").handler(rc -> {
        rc.response().setChunked(true).putHeader("Content-Type", "text/plain");
        vertx.setPeriodic(1000, l -> {
            if (rc.response().closed()) {
                System.out.println("Stopping"); //Doesn't happen
                vertx.cancelTimer(l);
            }
            try {
                System.out.println("hello"); // Keeps printing long after the client disconnects
                rc.response().write("hello\n");
            } catch (Exception e) {
                e.printStackTrace(); // Doesn't happen
                rc.response().close();
            }
        });

    });
    server.requestHandler(router::accept).listen(8080);
}
Malt
  • 28,965
  • 9
  • 65
  • 105
  • Seems you should end the response at some right moment: ```rc.response().end()``` – Nolequen Jan 11 '18 at 08:04
  • @Nolequen There are legitimate uses for endless chunked responses. Also, it turned out that it's a bug in Vert.x. – Malt Jan 11 '18 at 11:21

2 Answers2

2

Here is a solution waiting Vert.x 3.5.1. I hope that it will be helpfull for you :)

router.route("/hello").handler(rc -> {
    rc.response().setChunked(true).putHeader("Content-Type", "text/plain");
    final long timer = vertx.setPeriodic(1000, l -> {
        try {
            System.out.println("hello");
            rc.response().write("hello\n");
        } catch (Exception e) {
            e.printStackTrace();
            rc.response().close();
        }
    });

    // Handle close event to cancel the timer
    rc.response().closeHandler(evt -> {
        System.out.println("Stopping");
        vertx.cancelTimer(timer);
    });
});    
0

The issue turned out to be a bug in Vert.x (link). I was using version 3.5.0. It should be fixed in 3.5.1.

Malt
  • 28,965
  • 9
  • 65
  • 105