Common/known issues:
Possible explanations:
As explained in the "What Socket.IO is not" section, the Socket.IO client is not a WebSocket implementation and thus will not be able to establish a connection with a WebSocket server, even with transports: ["websocket"]:
const socket = io("ws://echo.websocket.org", {
transports: ["websocket"]
});
Please make sure the Socket.IO server is actually reachable at the given URL. You can test it with:
curl "<the server URL>/socket.io/?EIO=4&transport=polling"
which should return something like this:
0{"sid":"Lbo5JLzTotvW3g2LAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":20000}
If that's not the case, please check that the Socket.IO server is running, and that there is nothing in between that prevents the connection.
Here is the compatibility table for the JS client:
| JS Client version | Socket.IO server version | |||
|---|---|---|---|---|
| 1.x | 2.x | 3.x | 4.x | |
| 1.x | YES | NO | NO | NO |
| 2.x | NO | YES | YES1 | YES1 |
| 3.x | NO | NO | YES | YES |
| 4.x | NO | NO | YES | YES |
[1] Yes, with allowEIO3: true
Here is the compatibility table for the Java client:
| Java Client version | Socket.IO server version | ||
|---|---|---|---|
| 2.x | 3.x | 4.x | |
| 1.x | YES | YES1 | YES1 |
| 2.x | NO | YES | YES |
[1] Yes, with allowEIO3: true
Here is the compatibility table for the Swift client:
| Swift Client version | Socket.IO server version | ||
|---|---|---|---|
| 2.x | 3.x | 4.x | |
| v15.x | YES | YES1 | YES2 |
| v16.x | YES3 | YES | YES |
[1] Yes, with allowEIO3: true (server) and .connectParams(["EIO": "3"]) (client):
SocketManager(socketURL: URL(string:"http://localhost:8087/")!, config: [.connectParams(["EIO": "3"])])
[2] Yes, allowEIO3: true (server)
[3] Yes, with .version(.two) (client):
SocketManager(socketURL: URL(string:"http://localhost:8087/")!, config: [.version(.two)])
If you see the following error in your console:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at ...
It probably means that:
Please see the documentation here.
When scaling to multiple Socket.IO servers, you need to make sure that all the requests of a given Socket.IO session reach the same Socket.IO server. The explanation can be found here.
Failure to do so will result in HTTP 400 responses with the code: {"code":1,"message":"Session ID unknown"}
Please see the documentation here.
First and foremost, please note that disconnections are common and expected, even on a stable Internet connection:
That being said, the Socket.IO client will always try to reconnect, unless specifically told otherwise.
Possible explanations for a disconnection:
When a browser tab is not in focus, some browsers (like Chrome) throttle JavaScript timers, which could lead to a disconnection by ping timeout in Socket.IO v2, as the heartbeat mechanism relied on setTimeout function on the client side.
As a workaround, you can increase the pingTimeout value on the server side:
const io = new Server({
pingTimeout: 60000
});
Please note that upgrading to Socket.IO v4 (at least [email protected], due to this) should prevent this kind of issues, as the heartbeat mechanism has been reversed (the server now sends PING packets).
Since the format of the packets sent over the WebSocket transport is similar in v2 and v3/v4, you might be able to connect with an incompatible client (see above), but the connection will eventually be closed after a given delay.
So if you are experiencing a regular disconnection after 30 seconds (which was the sum of the values of pingTimeout and pingInterval in Socket.IO v2), this is certainly due to a version incompatibility.
If you get disconnected while sending a huge payload, this may mean that you have reached the maxHttpBufferSize value, which defaults to 1 MB. Please adjust it according to your needs:
const io = require("socket.io")(httpServer, {
maxHttpBufferSize: 1e8
});
A huge payload taking more time to upload than the value of the pingTimeout option can also trigger a disconnection (since the heartbeat mechanism fails during the upload). Please adjust it according to your needs:
const io = require("socket.io")(httpServer, {
pingTimeout: 60000
});
In most cases, you should see something like this:
zBjrh...AAAK — that is used in subsequent requests)auth option)If you don't see a HTTP 101 Switching Protocols response for the 4th request, that means that something between the server and your browser is preventing the WebSocket connection.
Please note that this is not necessarily blocking since the connection is still established with HTTP long-polling, but it is less efficient.
You can get the name of the current transport with:
Client-side
socket.on("connect", () => {
const transport = socket.io.engine.transport.name; // in most cases, "polling"
socket.io.engine.on("upgrade", () => {
const upgradedTransport = socket.io.engine.transport.name; // in most cases, "websocket"
});
});
Server-side
io.on("connection", (socket) => {
const transport = socket.conn.transport.name; // in most cases, "polling"
socket.conn.on("upgrade", () => {
const upgradedTransport = socket.conn.transport.name; // in most cases, "websocket"
});
});
Possible explanations:
Please see the documentation here.
© 2014–2021 Automattic
Licensed under the MIT License.
https://socket.io/docs/v4/troubleshooting-connection-issues