Commit Graph

706 Commits

Author SHA1 Message Date
Damien Arrachequesne
e20d487ac0 fix: properly export the Socket class
Before this change, `require("socket.io-client").Socket` would return
"undefined".

Note: having access to the Socket class allows users to modify its
prototype.

Related: https://github.com/socketio/socket.io/issues/3726
2021-05-06 14:24:08 +02:00
Damien Arrachequesne
34f822f783 fix: ensure buffered events are sent in order
Before this commit, an event sent in the "connect" handler could be
sent before the events that were buffered while disconnected.

```js
socket.on("connect", () => {
  socket.emit("bar");
});

socket.emit("foo"); // buffered while disconnected
```

In the example above, the "bar" event was sent first, which is not
correct.

Related: https://github.com/socketio/socket.io-client/issues/1458
2021-05-06 14:23:25 +02:00
Damien Arrachequesne
dd2a8fce00 fix: ensure connections are properly multiplexed
When passing the same `options` argument for two distinct Socket
instances, a new Manager was created:

```js
const opts = {};

const socket1 = io("/foo", opts);
const socket2 = io("/bar", opts);

console.log(socket1.io === socket2.io); // false
```

This bug was introduced by [1].

Note: the `options` argument is modified at the `socket.io-client`
level (path, query) and at the `engine.io-client` level (host, port),
which may not be optimal.

[1]: 7a0c2b504f

Related: https://github.com/socketio/socket.io/issues/3898
2021-05-06 14:22:54 +02:00
divlo
c15022347c fix(typings): make auth property public (#1455)
Related: https://github.com/socketio/socket.io-client/issues/1453
2021-04-01 00:32:21 +02:00
alex.zeng
48f573f6f6 fix(typings): update definition to match wrapper.mjs (#1456) 2021-04-01 00:31:43 +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
Damien Arrachequesne
7a0c2b504f fix: include the path in the manager ID
Previously, the following code:

```js
const socket1 = io({
  path: "/test1"
});
const socket2 = io({
  path: "/test2"
});
```

would result in one single Manager, with the "/test2" path being
silently ignored.

Two distinct Manager instances will now be created.

Related: https://github.com/socketio/socket.io-client/issues/1225
2021-02-03 22:31:01 +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
Damien Arrachequesne
53c73749a8 fix: emit a connect_error event upon connection failure
Related: https://github.com/socketio/socket.io/issues/3734
2021-01-05 11:42:54 +01:00
Damien Arrachequesne
b83f89c901 fix(typings): make sendBuffer and receiveBuffer public
See also: https://socket.io/docs/v3/client-offline-behavior/#Buffered-events
2021-01-05 10:17:58 +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
Damien Arrachequesne
ec1f8c3474 fix: emit an error when reaching a v2.x server
A WebSocket-only v3.x client is able to reach a v2.x server, as the
Engine.IO handshake are compatible, but the v2.x server does not send
a sid in the Socket.IO handshake, which resulted in:

> Uncaught TypeError: Cannot read property 'sid' of undefined

A 'connect_error' event will now be emitted.

References:

- https://github.com/socketio/engine.io-protocol#difference-between-v3-and-v4
- https://github.com/socketio/socket.io-protocol#difference-between-v5-and-v4
- https://socket.io/docs/v3/migrating-from-2-x-to-3-0/
2020-12-07 11:18:55 +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
Yusuke Sakurai
96cd2c9ae4 fix(typings): export ManagerOptions (#1398) 2020-11-17 00:03:22 +01:00
Avi Vahl
19ab1e9e4e fix(typings): export Socket and SocketOptions types (#1394)
These were exposed by @types/socket.io-client.
2020-11-09 09:00:07 +01:00
Damien Arrachequesne
09393952e3 feat: emit an Error object upon middleware error
See 54bf4a44e9
2020-10-30 22:54:13 +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
13e1db7c94 refactor: rename ERROR to CONNECT_ERROR
The meaning is not modified: this packet type is still used by the
server when the connection to a namespace is refused.

Breaking change: the Socket instance will now emit a "connect_error"
event instead of "error" (which is not a reserved event anymore)

```js
// before
socket.on("error", () => {});

// after
socket.on("connect_error", () => {});
```
2020-10-26 10:04:05 +01:00
Damien Arrachequesne
55f464f59e feat: add support for catch-all listeners
Inspired from EventEmitter2 [1]

The API is similar to the one on the server-side:

```js
socket.onAny((event, ...args) => {});

socket.prependAny((event, ...args) => {});

socket.offAny(); // remove all listeners

socket.offAny(listener);

const listeners = socket.listenersAny();
```

[1]: https://github.com/EventEmitter2/EventEmitter2
2020-10-26 10:03:27 +01:00
Damien Arrachequesne
f3cbe983a1 refactor: additional typings 2020-10-17 03:37:53 +02:00
Damien Arrachequesne
7ddad2c09d feat: add volatile events
A volatile packet will be dropped if:

- the socket is not connected
- the low-level transport is not ready (for example, a HTTP POST request is already pending)

Syntax:

```js
socket.volatile.emit("volatile event", "might or might not be sent");
```
2020-10-17 03:37:29 +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
b60e909039 refactor: remove the 'connecting' event
This event was added in 41956806a7

But it does not convey the information that the Socket is actually
sending a CONNECT packet to the server. It should maybe be moved to the
Socket#onopen() method, but let's remove it for now as it is not
documented anywhere.
2020-10-12 15:03:09 +02:00
Damien Arrachequesne
6494f61be0 feat: throw upon reserved event names
These events cannot be used by the end users, because they are part of
the Socket.IO public API, so using them will now throw an error
explicitly.

Related: f7ed81e5d2
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
249e0bef90 feat: remove the implicit connection to the default namespace
Related: 09b6f23339
2020-10-08 02:04:03 +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
Luke Olney
050108b228 fix: fix reconnection after opening socket asynchronously (#1253)
Closes https://github.com/socketio/socket.io/issues/3358
2020-09-30 16:01:15 +02:00
Damien Arrachequesne
b7dbbd28c8 test: fix race condition in the tests
Even with a timeout of 0, the 'open' event was emitted before the
timeout was reached, so the tests would randomly fail in the CI.
2020-09-30 00:07:29 +02:00
Damien Arrachequesne
eeafa44d01 [fix] Remove any reference to the global variable
Related: https://github.com/socketio/socket.io-client/issues/1166
2018-11-28 22:48:12 +01:00
Damien Arrachequesne
0fe9439ff6 [fix] Fire an error event on middleware failure for non-root namespace (#1202)
In the following example:

```js
io.use((socket, next) => {
  next(new Error('Auth failed'));
});

// client-side
const socket = io('https://url/custom-namespace');

socket.on('error', (err) => {
  // ...
});
```

The 'error' event wasn't fired on the custom namespace.
2018-05-17 22:53:37 +02:00
Damien Arrachequesne
74893d53ca [feat] Add a 'binary' flag (#1194)
So that the call to the `has-binary` method can be skipped. Usage:

```
// with binary data
socket.binary(true).emit("binary", obj);

// without binary data
socket.binary(false).emit("string", obj);

// call to hasBin
socket.emit("guess", obj);
```
2018-03-10 07:49:12 +01:00
Damien Arrachequesne
8091591422 [fix] Do not update the opts.query reference (#1121) 2017-06-01 12:35:31 +02:00
Damien Arrachequesne
ff4cb3eed0 [feat] Move binary detection to the parser (#1103) 2017-04-25 00:28:50 +02:00
Damien Arrachequesne
2dcc794b8f [feature] Allow the use of a custom parser (#1075)
See https://github.com/socketio/socket.io/pull/2829
2017-02-20 21:46:02 +01:00
Jianru Lin
4322cf200f [docs] Fix typo (#1076) 2017-02-20 13:44:20 +01:00
Damien Arrachequesne
fcb5c43ffe [fix] Add nsp prefix to socket.id (#1058)
So the socket ids on the client and on the server are equals.
2017-01-13 16:53:44 +01:00