Fork me on GitHub

Emitting events

See also: https://socket.io/docs/v4/emitting-events/

Table of content

There are several ways to send events between the server and the client.

Basic emit

The Socket.IO API is inspired from the Node.js EventEmitter:

Server

io.on("connection", (socket) => {
  socket.emit("hello", "world");
});

Client

socket.on("hello", new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        System.out.println(args[0]); // world
    }
});

This also works in the other direction:

Server

io.on("connection", (socket) => {
  socket.on("hello", (arg) => {
    console.log(arg); // world
  });
});

Client

socket.emit("hello", "world");

You can send any number of arguments, and all serializable datastructures are supported, including binary objects like Buffer or TypedArray.

Server

io.on("connection", (socket) => {
  socket.on("hello", (...args) => {
    console.log(args); // [ 1, '2', <Buffer 61 62 63>, { test: '42' } ]
  });
});

Client

byte[] buffer = "abc".getBytes(StandardCharsets.UTF_8);
JSONObject object = new JSONObject();
object.put("test", "42");

socket.emit("hello", 1, "2", bytes, object);

Acknowledgements

Events are great, but in some cases you may want a more classic request-response API. In Socket.IO, this feature is named acknowledgements.

You can add a callback as the last argument of the emit(), and this callback will be called once the other side acknowledges the event:

From client to server

Client

// Java 7
socket.emit("update item", 1, new JSONObject(singletonMap("name", "updated")), new Ack() {
    @Override
    public void call(Object... args) {
        JSONObject response = (JSONObject) args[0];
        System.out.println(response.getString("status")); // "ok"
    }
});

// Java 8 and above
socket.emit("update item", 1, new JSONObject(singletonMap("name", "updated")), (Ack) args -> {
    JSONObject response = (JSONObject) args[0];
    System.out.println(response.getString("status")); // "ok"
});

Server

io.on("connection", (socket) => {
  socket.on("update item", (arg1, arg2, callback) => {
    console.log(arg1); // 1
    console.log(arg2); // { name: "updated" }
    callback({
      status: "ok"
    });
  });
});

From server to client

Server

io.on("connection", (socket) => {
  socket.emit("hello", "please acknowledge", (response) => {
    console.log(response); // prints "hi!"
  });
});

Client

// Java 7
socket.on("hello", new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        System.out.println(args[0]); // "please acknowledge"
        if (args.length > 1 && args[1] instanceof Ack) {
            ((Ack) args[1]).call("hi!");
        }
    }
});

// Java 8 and above
socket.on("hello", args -> {
    System.out.println(args[0]); // "please acknowledge"
    if (args.length > 1 && args[1] instanceof Ack) {
        ((Ack) args[1]).call("hi!");
    }
});

With timeout

Starting with version 2.1.0, you can now assign a timeout to each emit:

socket.emit("hello", "world", new AckWithTimeout(5000) {
    @Override
    public void onTimeout() {
        // ...
    }

    @Override
    public void onSuccess(Object... args) {
        // ...
    }
});