Initialization
Table of content
Creation of a Socket instance
URI uri = URI.create("https://example.com");
IO.Options options = IO.Options.builder()
// ...
.build();
Socket socket = IO.socket(uri, options);
Unlike the JS client (which can infer it from the window.location object), the URI is mandatory here.
The scheme part of the URI is also mandatory. Both ws:// and http:// can be used interchangeably.
Socket socket = IO.socket("https://example.com"); // OK
Socket socket = IO.socket("wss://example.com"); // OK, similar to the example above
Socket socket = IO.socket("192.168.0.1:1234"); // NOT OK, missing the scheme part
The path represents the Namespace, and not the actual path (see below) of the HTTP requests:
Socket socket = IO.socket(URI.create("https://example.com")); // the main namespace
Socket productSocket = IO.socket(URI.create("https://example.com/product")); // the "product" namespace
Socket orderSocket = IO.socket(URI.create("https://example.com/order")); // the "order" namespace
Default values
IO.Options options = IO.Options.builder()
// IO factory options
.setForceNew(false)
.setMultiplex(true)
// low-level engine options
.setTransports(new String[] { Polling.NAME, WebSocket.NAME })
.setUpgrade(true)
.setRememberUpgrade(false)
.setPath("/socket.io/")
.setQuery(null)
.setExtraHeaders(null)
// Manager options
.setReconnection(true)
.setReconnectionAttempts(Integer.MAX_VALUE)
.setReconnectionDelay(1_000)
.setReconnectionDelayMax(5_000)
.setRandomizationFactor(0.5)
.setTimeout(20_000)
// Socket options
.setAuth(null)
.build();
Description
IO factory options
These settings will be shared by all Socket instances attached to the same Manager.
forceNew
Default value: false
Whether to create a new Manager instance.
A Manager instance is in charge of the low-level connection to the server (established with HTTP long-polling or WebSocket). It handles the reconnection logic.
A Socket instance is the interface which is used to sends events to — and receive events from — the server. It belongs to a given namespace.
A single Manager can be attached to several Socket instances.
The following example will reuse the same Manager instance for the 3 Socket instances (one single WebSocket connection):
IO.Options options = IO.Options.builder()
.setForceNew(false)
.build();
Socket socket = IO.socket(URI.create("https://example.com"), options); // the main namespace
Socket productSocket = IO.socket(URI.create("https://example.com/product"), options); // the "product" namespace
Socket orderSocket = IO.socket(URI.create("https://example.com/order"), options); // the "order" namespace
The following example will create 3 different Manager instances (and thus 3 distinct WebSocket connections):
IO.Options options = IO.Options.builder()
.setForceNew(true)
.build();
Socket socket = IO.socket(URI.create("https://example.com"), options); // the main namespace
Socket productSocket = IO.socket(URI.create("https://example.com/product"), options); // the "product" namespace
Socket orderSocket = IO.socket(URI.create("https://example.com/order"), options); // the "order" namespace
multiplex
Default value: true
The opposite of forceNew: whether to reuse an existing Manager instance.
Low-level engine options
transports
Default value: new String[] { Polling.NAME, WebSocket.NAME }
The low-level connection to the Socket.IO server can either be established with:
- HTTP long-polling: successive HTTP requests (
POSTfor writing,GETfor reading) - WebSocket
The following example disables the HTTP long-polling transport:
IO.Options options = IO.Options.builder()
.setTransports(new String[] { WebSocket.NAME })
.build();
Socket socket = IO.socket(URI.create("https://example.com"), options);
Note: in that case, sticky sessions are not required on the server side (more information here).
upgrade
Default value: true
Whether the client should try to upgrade the transport from HTTP long-polling to something better.
rememberUpgrade
Default value: false
If true and if the previous WebSocket connection to the server succeeded, the connection attempt will bypass the normal upgrade process and will initially try WebSocket. A connection attempt following a transport error will use the normal upgrade process. It is recommended you turn this on only when using SSL/TLS connections, or if you know that your network does not block websockets.
path
Default value: /socket.io/
It is the name of the path that is captured on the server side.
The server and the client values must match:
Server
import { Server } from "socket.io";
const io = new Server(8080, {
path: "/my-custom-path/"
});
io.on("connection", (socket) => {
// ...
});
Client
IO.Options options = IO.Options.builder()
.setPath("/my-custom-path/")
.build();
Socket socket = IO.socket(URI.create("https://example.com"), options);
Please note that this is different from the path in the URI, which represents the Namespace.
Example:
IO.Options options = IO.Options.builder()
.setPath("/my-custom-path/")
.build();
Socket socket = IO.socket(URI.create("https://example.com/order"), options);
- the Socket instance is attached to the “order” Namespace
- the HTTP requests will look like:
GET https://example.com/my-custom-path/?EIO=4&transport=polling&t=ML4jUwU
query
Default value: -
Additional query parameters (then found in socket.handshake.query object on the server-side).
Example:
Server
io.on("connection", (socket) => {
console.log(socket.handshake.query); // prints { x: '42', EIO: '4', transport: 'polling' }
});
Client
IO.Options options = IO.Options.builder()
.setQuery("x=42")
.build();
Socket socket = IO.socket(URI.create("https://example.com"), options);
Note: The socket.handshake.query object contains the query parameters that were sent during the Socket.IO handshake, it won’t be updated for the duration of the current session, which means changing the query on the client-side will only be effective when the current session is closed and a new one is created:
socket.io().on(Manager.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
@Override
public void call(Object... args) {
options.query = "y=43";
}
});
extraHeaders
Default value: -
Additional headers (then found in socket.handshake.headers object on the server-side).
Example:
Server
io.on("connection", (socket) => {
console.log(socket.handshake.headers); // prints { accept: '*/*', authorization: 'bearer 1234', connection: 'Keep-Alive', 'accept-encoding': 'gzip', 'user-agent': 'okhttp/3.12.12' }
});
Client
IO.Options options = IO.Options.builder()
.setExtraHeaders(singletonMap("authorization", singletonList("bearer 1234")))
.build();
Socket socket = IO.socket(URI.create("https://example.com"), options);
Note: Similar to the query option above, the socket.handshake.headers object contains the headers that were sent during the Socket.IO handshake, it won’t be updated for the duration of the current session, which means changing the extraHeaders on the client-side will only be effective when the current session is closed and a new one is created:
socket.io().on(Manager.EVENT_RECONNECT_ATTEMPT, new Emitter.Listener() {
@Override
public void call(Object... args) {
options.extraHeaders.put("authorization", singletonList("bearer 5678"));
}
});
Socket options
These settings are specific to the given Socket instance.
auth
Default value: -
Credentials that are sent when accessing a namespace (see also here).
Example:
Server
io.on("connection", (socket) => {
console.log(socket.handshake.auth); // prints { token: 'abcd' }
});
Client
IO.Options options = IO.Options.builder()
.setAuth(singletonMap("token", "abcd"))
.build();
Socket socket = IO.socket(URI.create("https://example.com"), options);
You can update the auth map when the access to the Namespace is denied:
socket.on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
@Override
public void call(Object... args) {
options.auth.put("token", "efgh");
socket.connect();
}
});
Or manually force the Socket instance to reconnect:
options.auth.put("token", "efgh");
socket.disconnect().connect();
