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.
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);If you intend to send structured data, do not pass a JSON-looking string like "{me: 1449240991}". Send a JSONObject (or JSONArray) instead. Strings will be delivered as plain strings on the server.
Client (wrong):
socket.emit("authentication", "{me: 1449240991}"); // sent as a String, not an objectClient (correct):
JSONObject payload = new JSONObject().put("me", 1449240991);
socket.emit("authentication", payload);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:
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"
});
});
});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!");
}
});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) {
// ...
}
});