Commit Graph

38 Commits

Author SHA1 Message Date
Max Stepanov
f2892aba0b fix: use same scope for setTimeout and clearTimeout calls (#1568)
Details:

- engine.io-client sets clearTimeoutFn and setTimeoutFn function
  depending on settings passed to manager

- socker.io-client is using manager.setTimeoutFn to start connection
  monitoring timer, but is using regular clearTimeout function to
  stop it when connection is established

- in some setups it is causing timer fail to stop and it will break
  connection every _timeout_ milliseconds (which is 20000 by default)
2023-06-22 09:33:11 +02:00
Damien Arrachequesne
5bc94b56bc fix: properly report timeout error when connecting
In some specific cases (Node.js client with WebSocket only), the reason
attached to the "connect_error" event was "websocket error" instead of
"timeout".

Related: https://github.com/socketio/socket.io/issues/4062
2023-06-20 18:48:11 +02:00
Damien Arrachequesne
46213a647e fix: prevent duplicate connections when multiplexing
This bug was introduced in [1]: a multiplexed socket could in some
cases send multiple CONNECT packets, resulting in duplicate connections
on the server side.

A cached socket will now be reopened only if it was inactive, that is,
if one had explicitly called socket.disconnect() before.

Related: https://github.com/socketio/socket.io-client/issues/1460

[1]: b7dd891e89
2023-02-20 17:09:50 +01:00
Damien Arrachequesne
b7dd891e89 fix: ensure manager.socket() returns an active socket
Related: https://github.com/socketio/socket.io-client/issues/1460
2023-02-03 08:16:38 +01:00
Damien Arrachequesne
2403b88057 fix: do not swallow user exceptions
Following [1], any exception in a user-provided event listener would
get caught in the try...catch of the decoder and result in the
reconnection of the socket.

[1]: c597023169

Related:

- https://github.com/socketio/socket.io-client/issues/1551
- https://github.com/socketio/socket.io-client/issues/1554
- https://github.com/socketio/socket.io-client/issues/1557
2022-10-13 16:26:35 +02:00
Damien Arrachequesne
c597023169 fix: handle ill-formatted packet from server
The decoder can throw an error when trying to decode an invalid payload
sent by the server, so the manager will now catch it, close the
connection and then reconnect instead of crashing.

Related:

- https://github.com/socketio/socket.io/issues/4392
- https://github.com/socketio/socket.io-client/issues/1551
2022-09-02 23:28:35 +01:00
Damien Arrachequesne
6fdf3c9bfa refactor: import single-file 3rd party modules
This commit allows to:

- provide an ESM version of those modules ([1])
- reduce the attack surface in case of supply chain attacks
- reduce the size of the bundle with tree-shaking

As a downside, we won't receive security updates for those modules
anymore.

[1]: socketio/socket.io-client#1536

Related: df32277c3f
2022-04-23 22:55:39 +02:00
Damien Arrachequesne
b862924b7f feat: add details to the disconnect event
The "disconnect" event will now include additional details to help
debugging if anything has gone wrong.

Example when a payload is over the maxHttpBufferSize value in HTTP
long-polling mode:

```js
socket.on("disconnect", (reason, details) => {
  console.log(reason); // "transport error"

  // in that case, details is an error object
  console.log(details.message); "xhr post error"
  console.log(details.description); // 413 (the HTTP status of the response)

  // details.context refers to the XMLHttpRequest object
  console.log(details.context.status); // 413
  console.log(details.context.responseText); // ""
});
```

Related: b9252e2074
2022-04-23 00:57:23 +02:00
Damien Arrachequesne
99c2cb8421 fix: fix socket.disconnect().connect() usage
Previously, calling `socket.disconnect().connect()` could, if the
connection was upgraded to WebSocket, result in "disconnect" being
emitted twice, and an engine being leaked.

Here's what happened:

> socket.disconnect()

- calls `socket.destroy()` so the socket doesn't listen to the manager events anymore
- then calls `manager._close()` which closes the underlying engine but not the manager itself (it waits for the "close" event of the engine)

> socket.connect()

- calls `socket.subEvents()` so the socket does listen to the manager events
- calls `manager.open()` which creates a new engine

And then the first engine emits a "close" event, which is forwarded to
the socket, hence the second "disconnect" event.

Related: https://github.com/socketio/socket.io-client/issues/1014
2021-11-18 13:39:40 +01:00
Damien Arrachequesne
91b948b860 refactor: move the typed events to @socket.io/component-emitter
The typed events have been moved to [1] in order to remove the
intermediary class and reduce the bundle size.

Diff: https://github.com/socketio/emitter/compare/2.0.0...3.0.0

[1]: https://github.com/socketio/emitter/
2021-10-14 14:09:23 +02:00
Damien Arrachequesne
16b65698ae feat: provide an ESM build with and without debug
See also: 00d7e7d7ee

Related:

- https://github.com/socketio/socket.io-client/issues/1188
- https://github.com/socketio/socket.io-client/issues/1378
2021-10-13 18:09:41 +02:00
Damien Arrachequesne
91fbd47e1e chore: bump engine.io-client to version 6.0.0
Release notes: https://github.com/socketio/engine.io-client/releases/6.0.0
Diff: https://github.com/socketio/engine.io-client/compare/5.2.0...6.0.0
2021-10-11 23:19:51 +02:00
Michael Vartan
4e1b65699d feat: add an option to use native timer functions (#1479)
This allows to control the behavior of mocked timers (@sinonjs/fake-timers),
depending on the value of the "useNativeTimers" option:

- true: use native setTimeout function
- false (default): use classic timers, that may be mocked

Related: 5d1d5bea11
2021-08-29 09:31:25 +02:00
vks-jrobertson
dfb46b55a5 fix: allow to set randomizationFactor to 0 (#1447)
Documentation: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#nullish-coalescing

Related: https://github.com/socketio/socket.io-client/issues/1231
2021-07-29 09:59:03 +02:00
javiergonzalezGenially
35d27df2ae fix(typings): add missing closeOnBeforeunload option (#1469) 2021-05-17 22:01:39 +02:00
Poyan Nabati
c8dfbb1c1d fix(typings): add missing requestTimeout option (#1467) 2021-05-17 00:39:29 +02:00
KC Erb
6abfa1fa4c feat: add autoUnref option
With autoUnref set to true (default: false), the Socket.IO client will
allow the program to exit if there is no other active timer/socket in
the event system.

```js
const socket = io({
  autoUnref: true
});
```

Note: this option only applies to Node.js clients.

Related: https://github.com/socketio/socket.io-client/issues/1446
2021-03-10 12:16:12 +01:00
Damien Arrachequesne
59023657a0 feat: add support for typed events
Syntax:

```ts
interface ServerToClientEvents {
  "my-event": (a: number, b: string, c: number[]) => void;
}

interface ClientToServerEvents {
  hello: (message: string) => void;
}

const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io();

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

socket.on("my-event", (a, b, c) => {
  // ...
});
```

The events are not typed by default (inferred as any), so this change
is backward compatible.

Related: https://github.com/socketio/socket.io/issues/3742
2021-03-10 01:24:56 +01:00
david-fong
47f917afdd fix(typings): add return types and general-case overload signatures (#1440) 2021-02-02 11:29:08 +01:00
Mick Lawitzke
f02ab3bc96 fix(typings): fix the type of the "query" option (#1439)
Having type `Object` it was not possible to set values, e.g.:

```ts
if (!this.socket.io.opts.query) {
  this.socket.io.opts.query = {};
}
this.socket.io.opts.query.token = 'abc123';
```

Results in error:

> Element implicitly has an 'any' type because expression of type '"token"' can't be used to index type 'Object'.
2021-02-02 11:26:33 +01:00
Damien Arrachequesne
0a63a17f63 refactor: remove unused line
In Socket.IO v2, the Socket `query` option was sent when connecting to
a custom namespace (but not for the main namespace).

This was fixed in Socket.IO v3 ([1]), so this line is now useless.

[1]: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/#Add-a-clear-distinction-between-the-Manager-query-option-and-the-Socket-query-option
2021-01-28 12:27:02 +01:00
Mick Lawitzke
fe97243fab fix(typings): make Manager#opts public (#1437)
As stated in the [documentation][1], the query option can be set by
setting `socket.io.opts` but `opts` was private and readonly.

[1]: https://socket.io/docs/v3/client-api/#With-query-option
2021-01-11 22:47:28 +01:00
david-fong
7bc7a7b624 refactor: switch to native javascript bind (#1423)
The polyfill for the bind() method was necessary for IE6/7/8, which we
do not support anymore.

Related: https://caniuse.com/mdn-javascript_builtins_function_bind
2020-12-11 11:55:57 +01:00
Damien Arrachequesne
f8f60fc860 fix: keep track of active sockets
When a given socket was disconnected, either by the server-side or by the client-side, the manager was closed too, regardless of the other connected sockets.

```js
const socket1 = io({
  autoConnect: false
});
const socket2 = io("/test");

socket1.disconnect(); // also disconnect socket2
```

This bug was introduced in [1].

[1]: b60e909039
2020-12-07 11:24:15 +01:00
david-fong
226b491846 refactor(typings): make typing information more specific (#1418) 2020-12-07 09:06:57 +01:00
Luiz Pereira
b3de861a92 fix(typings): export extraHeaders option (#1410) 2020-11-20 23:09:27 +01:00
Damien Arrachequesne
719307801a fix(typings): export withCredentials option
Related: https://github.com/socketio/socket.io-client/issues/1405
2020-11-17 23:54:57 +01:00
Damien Arrachequesne
969debe88c refactor: rework of the Manager events
- rename "connect_error" to "error"
- remove "reconnecting" (duplicate of "reconnect_attempt")

The updated list of events emitted by the Manager:

- open:                successful (re)connection
- error:               (re)connection failure (previously: "connect_error") or error after a successful connection
- close:               disconnection

- ping:                ping packet
- packet:              data packet

- reconnect_attempt:   reconnection attempt (previously: "reconnect_attempt" & "reconnecting")
- reconnect:           successful reconnection
- reconnect_error:     reconnection failure
- reconnect_failed:    reconnection failure after all attempts

For reference, the Socket instance emits the following events:

- connect:             successful connection to a Namespace
- connect_error:       connection failure
- disconnect:          disconnection
2020-10-27 23:07:44 +01:00
Damien Arrachequesne
f3cbe983a1 refactor: additional typings 2020-10-17 03:37:53 +02:00
Damien Arrachequesne
178909471a feat: move binary detection back to the parser
See 285e7cd0d8

Breaking change: the Socket#binary() method is removed, as this use
case is now covered by the ability to provide your own parser.
2020-10-15 10:37:06 +02:00
Damien Arrachequesne
c7998d5446 refactor: add Manager and Socket typings 2020-10-14 22:59:58 +02:00
Damien Arrachequesne
e826992c8e refactor: remove the 'connect_timeout' event
The 'connect_timeout' event is now merged with the 'connect_error'
event, and will now emit an Error object instead of a plain string.
2020-10-12 15:03:09 +02:00
Damien Arrachequesne
132f8ec918 feat: split the events of the Manager and Socket
Previously, most of the events emitted by the Manager were also emitted
by the Socket instances, but it was somehow misleading for the end
users because they don't have the same meaning:

- Manager: the state of the low-level connection (with connection and reconnection events)
- Socket: the state of the connection to the Namespace (only 'connect', 'disconnect' and 'error')

For example, the `reconnect` event:

```js
socket.on("reconnect", () => {
  console.log(socket.connected); // might be false, which is a bit surprising
});
```

Breaking change: the Socket instance will no longer forward the events
of its Manager

Those events can still be accessed on the Manager instance though:

```js
socket.io.on("reconnect", () => {
  // ...
});
```
2020-10-12 15:03:09 +02:00
Damien Arrachequesne
6cd2e4eab0 refactor: remove the packetBuffer array
The parser#encode() method is now synchronous, so the packetBuffer
array is useless.
2020-10-12 11:41:55 +02:00
Damien Arrachequesne
bbe94adb82 feat: do not reuse the Engine.IO id
Related: 3b0cb1158c
2020-10-08 03:04:49 +02:00
Damien Arrachequesne
be8c3141bd chore: include Engine.IO client v4
The ping-pong mechanism has been reverted (server now sends a ping and
expects a pong from the client), so we cannot compute the latency like
we did in previous versions.

Release notes: https://github.com/socketio/engine.io-client/releases/tag/4.0.0
2020-10-06 22:50:52 +02:00
Damien Arrachequesne
429846b0a1 chore: bump socket.io-parser
Breaking change:

- the encode() method is now synchronous

Please note that the exchange [protocol][1] is left untouched and thus
stays in version 4.

Diff: https://github.com/socketio/socket.io-parser/compare/3.4.1...4.0.0

[1] https://github.com/socketio/socket.io-protocol
2020-10-06 01:20:12 +02:00
Damien Arrachequesne
697bea2d81 refactor: migrate to TypeScript 2020-10-06 00:21:14 +02:00