docs: public CompletableFuture<Void> close() {
      if (open.compareAndSet(true, false)) {
        CompletableFuture<Void> future = new CompletableFuture<>();
        threadContext.execute(() -> {
          synchronized (this) {
            for (Scheduled keepAliveFuture : keepAliveTimers.values()) {
              keepAliveFuture.cancel();
            }
            protocol.unregisterHeartbeatHandler();
          }
          future.complete(null);
        });
        return future;
      }
      return CompletableFuture.completedFuture(null);
    }