Compare commits

..

18 Commits

Author SHA1 Message Date
Maxime Kjaer
f3ea96eb3a test: build examples in the CI (#3856) 2023-10-10 20:00:27 +02:00
abriejenny
c2858e911e docs(examples): update docker-compose.yml (#4594)
Updated docker compose to be in line with current practices.

Reference: https://docs.docker.com/compose/
2023-01-12 09:56:11 +01:00
Szegedi Ádám
2f96438952 chore: bump engine.io version to fix CVE-2022-21676 (#4262)
Related: https://github.com/socketio/engine.io/security/advisories/GHSA-273r-mgr4-v34f
2022-01-25 22:18:18 +01:00
Chris Swithinbank
02c87a8561 fix(typings): ensure compatibility with TypeScript 3.x (#4259)
Labeled tuple elements were added in TypeScript 4.0.

Reference: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#labeled-tuple-elements

Related: 44e20ba5bf
2022-01-25 01:25:05 +01:00
Damien Arrachequesne
37b6d8fff0 chore: update default label for bug reports 2022-01-10 08:55:56 +01:00
Damien Arrachequesne
af54565b2d docs: remove broken badges
Related: https://github.com/socketio/socket.io/issues/4242
2022-01-10 08:03:53 +01:00
Damien Arrachequesne
aa5312a4b6 chore: revert to lockfile v1
Updating to v2 fails in the CI on Node.js 12 & 14 with the following
error:

> npm ERR! Error while executing:
> npm ERR! /usr/bin/git ls-remote -h -t ssh://git@github.com/uNetworking/uWebSockets.js.git
> npm ERR!
> npm ERR! Warning: Permanently added the RSA host key for IP address '140.82.113.3' to the list of known hosts.
> npm ERR! git@github.com: Permission denied (publickey).
> npm ERR! fatal: Could not read from remote repository.
> npm ERR!
> npm ERR! Please make sure you have the correct access rights
> npm ERR! and the repository exists.
> npm ERR!
> npm ERR! exited with error code: 128

So we will revert the change for now.
2022-01-06 08:01:00 +01:00
Damien Arrachequesne
c82a4bdf1f chore(release): 4.4.1
Diff: https://github.com/socketio/socket.io/compare/4.4.0...4.4.1
2022-01-06 07:32:03 +01:00
Orkhan Alikhanov
770ee5949f fix(types): make RemoteSocket.data type safe (#4234)
Related:

- https://github.com/socketio/socket.io/issues/4229
- fe8730ca0f
2022-01-06 07:14:55 +01:00
Damien Arrachequesne
3bf5d92735 refactor: add note about fetchSockets() for parent namespaces
Related: https://github.com/socketio/socket.io/issues/4235
2022-01-05 08:50:40 +01:00
Shayan Yousefi
fc82e44f73 refactor(typings): export Event type (#4215)
So that it can be used by the end users:

```ts
const myMiddleware = ([eventName, ...args]: Event, next: (err?: Error) => void) => {
  console.log(eventName); // inferred as string
  next();
}

io.on("connection", (socket) => {
  socket.use(myMiddleware);
});
```
2022-01-05 08:08:18 +01:00
Damien Arrachequesne
c840bad43a test: fix flaky tests 2022-01-05 08:00:55 +01:00
Orkhan Alikhanov
f2b8de7191 fix(typings): pass SocketData type to custom namespaces (#4233)
The `SocketData` type was only available on the main namespace.

Related: https://github.com/socketio/socket.io/issues/4229
See also: fe8730ca0f
2022-01-04 09:09:42 +01:00
Gray Zhang
51784d0305 chore: add types to exports field to be compatible with nodenext module resolution (#4228)
See [1] for detail, in `nodenext` module resolution it requires a
`types` field in `exports` with full filename including extension.

[1]: https://github.com/microsoft/TypeScript/issues/46770#issuecomment-966612103
2021-12-28 10:27:08 +01:00
Damien Arrachequesne
c196689545 docs: fix basic crud example
Related: https://github.com/socketio/socket.io/issues/4213
2021-12-16 23:00:20 +01:00
Mikhail Dudin
7a70f63499 docs: fix reconnection handling in the chat demo app (#4189) 2021-12-01 00:03:43 +01:00
anderslatif
e5897dd7dc docs: add usage with ES modules (#4195) 2021-12-01 00:02:13 +01:00
Damien Arrachequesne
2071a66c5a docs: simplify nginx cluster example
- remove useless Dockerfile
- clean format
- migrate to @socket.io/redis-adapter
2021-11-24 18:15:26 +01:00
25 changed files with 262 additions and 259 deletions

View File

@@ -2,7 +2,7 @@
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'bug'
labels: 'to triage'
assignees: ''
---

View File

@@ -24,3 +24,31 @@ jobs:
- run: npm test
env:
CI: true
build-examples:
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
example:
- custom-parsers
- typescript
- webpack-build
- webpack-build-server
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Use Node.js 20
uses: actions/setup-node@v3
with:
node-version: 20
- name: Build ${{ matrix.example }}
run: |
cd examples/${{ matrix.example }}
npm install
npm run build

View File

@@ -1,3 +1,13 @@
## [4.4.1](https://github.com/socketio/socket.io/compare/4.4.0...4.4.1) (2022-01-06)
### Bug Fixes
* **types:** make `RemoteSocket.data` type safe ([#4234](https://github.com/socketio/socket.io/issues/4234)) ([770ee59](https://github.com/socketio/socket.io/commit/770ee5949fb47c2556876c622f06c862573657d6))
* **types:** pass `SocketData` type to custom namespaces ([#4233](https://github.com/socketio/socket.io/issues/4233)) ([f2b8de7](https://github.com/socketio/socket.io/commit/f2b8de71919e1b4d3e57f15a459972c1d1064787))
# [4.4.0](https://github.com/socketio/socket.io/compare/4.3.2...4.4.0) (2021-11-18)

View File

@@ -2,8 +2,6 @@
[![Run on Repl.it](https://repl.it/badge/github/socketio/socket.io)](https://replit.com/@socketio/socketio-minimal-example)
[![Backers on Open Collective](https://opencollective.com/socketio/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/socketio/sponsors/badge.svg)](#sponsors)
[![Build Status](https://github.com/socketio/socket.io/workflows/CI/badge.svg)](https://github.com/socketio/socket.io/actions)
[![Dependency Status](https://david-dm.org/socketio/socket.io.svg)](https://david-dm.org/socketio/socket.io)
[![devDependency Status](https://david-dm.org/socketio/socket.io/dev-status.svg)](https://david-dm.org/socketio/socket.io#info=devDependencies)
[![NPM version](https://badge.fury.io/js/socket.io.svg)](https://www.npmjs.com/package/socket.io)
![Downloads](https://img.shields.io/npm/dm/socket.io.svg?style=flat)
[![](https://slackin-socketio.now.sh/badge.svg)](https://slackin-socketio.now.sh)
@@ -115,6 +113,14 @@ io.on('connection', client => { ... });
io.listen(3000);
```
### Module syntax
```js
import { Server } from "socket.io";
const io = new Server(server);
io.listen(3000);
```
### In conjunction with Express
Starting with **3.0**, express applications have become request handler

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
/*!
* Socket.IO v4.4.0
* (c) 2014-2021 Guillermo Rauch
* Socket.IO v4.4.1
* (c) 2014-2022 Guillermo Rauch
* Released under the MIT License.
*/
(function (global, factory) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -7,8 +7,8 @@ export enum Errors {
const errorValues: string[] = Object.values(Errors);
export function sanitizeErrorMessage(message: string) {
if (errorValues.includes(message)) {
export function sanitizeErrorMessage(message: any) {
if (typeof message === "string" && errorValues.includes(message)) {
return message;
} else {
return "an unknown error has occurred";

View File

@@ -6,7 +6,7 @@ A simple chat demo for Socket.IO
## How to use
```
$ npm ci
$ npm i
$ npm start
```

View File

@@ -264,14 +264,14 @@ $(function() {
log('you have been disconnected');
});
socket.on('reconnect', () => {
socket.io.on('reconnect', () => {
log('you have been reconnected');
if (username) {
socket.emit('add user', username);
}
});
socket.on('reconnect_error', () => {
socket.io.on('reconnect_error', () => {
log('attempt to reconnect has failed');
});

View File

@@ -1,56 +1,43 @@
services:
nginx:
image: nginx:alpine
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "3000:80"
nginx:
build: ./nginx
links:
- server-john
- server-paul
- server-george
- server-ringo
ports:
- "3000:80"
server-john:
build: ./server
links:
- redis
expose:
server-john:
build: ./server
expose:
- "3000"
environment:
- NAME=John
environment:
- NAME=John
server-paul:
build: ./server
links:
- redis
expose:
- "3000"
environment:
- NAME=Paul
server-paul:
build: ./server
expose:
- "3000"
environment:
- NAME=Paul
server-george:
build: ./server
links:
- redis
expose:
- "3000"
environment:
- NAME=George
server-george:
build: ./server
expose:
- "3000"
environment:
- NAME=George
server-ringo:
build: ./server
links:
- redis
expose:
- "3000"
environment:
- NAME=Ringo
server-ringo:
build: ./server
expose:
- "3000"
environment:
- NAME=Ringo
client:
build: ./client
links:
- nginx
client:
build: ./client
redis:
image: redis:alpine
expose:
- "6379"
redis:
image: redis:alpine
expose:
- "6379"

View File

@@ -1,3 +0,0 @@
FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf

View File

@@ -1,15 +1,18 @@
// Setup basic express server
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var redis = require('socket.io-redis');
var port = process.env.PORT || 3000;
var serverName = process.env.NAME || 'Unknown';
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
const { createAdapter } = require('@socket.io/redis-adapter');
const { createClient } = require('redis');
const port = process.env.PORT || 3000;
const serverName = process.env.NAME || 'Unknown';
io.adapter(redis({ host: 'redis', port: 6379 }));
const pubClient = createClient({ host: 'redis', port: 6379 });
const subClient = pubClient.duplicate();
server.listen(port, function () {
io.adapter(createAdapter(pubClient, subClient));
server.listen(port, () => {
console.log('Server listening at port %d', port);
console.log('Hello, I\'m %s, how can I help?', serverName);
});
@@ -19,15 +22,15 @@ app.use(express.static(__dirname + '/public'));
// Chatroom
var numUsers = 0;
let numUsers = 0;
io.on('connection', function (socket) {
io.on('connection', socket => {
socket.emit('my-name-is', serverName);
var addedUser = false;
let addedUser = false;
// when the client emits 'new message', this listens and executes
socket.on('new message', function (data) {
socket.on('new message', data => {
// we tell the client to execute 'new message'
socket.broadcast.emit('new message', {
username: socket.username,
@@ -36,7 +39,7 @@ io.on('connection', function (socket) {
});
// when the client emits 'add user', this listens and executes
socket.on('add user', function (username) {
socket.on('add user', username => {
if (addedUser) return;
// we store the username in the socket session for this client
@@ -54,21 +57,21 @@ io.on('connection', function (socket) {
});
// when the client emits 'typing', we broadcast it to others
socket.on('typing', function () {
socket.on('typing', () => {
socket.broadcast.emit('typing', {
username: socket.username
});
});
// when the client emits 'stop typing', we broadcast it to others
socket.on('stop typing', function () {
socket.on('stop typing', () => {
socket.broadcast.emit('stop typing', {
username: socket.username
});
});
// when the user disconnects.. perform this
socket.on('disconnect', function () {
socket.on('disconnect', () => {
if (addedUser) {
--numUsers;

View File

@@ -7,9 +7,10 @@
"private": true,
"license": "MIT",
"dependencies": {
"@socket.io/redis-adapter": "^7.0.1",
"express": "4.13.4",
"socket.io": "^4.0.0",
"socket.io-redis": "^6.0.1"
"redis": "^3.1.2",
"socket.io": "^4.0.0"
},
"scripts": {
"start": "node index.js"

View File

@@ -9,7 +9,7 @@ import type {
TypedEventBroadcaster,
} from "./typed-events";
export class BroadcastOperator<EmitEvents extends EventsMap>
export class BroadcastOperator<EmitEvents extends EventsMap, SocketData>
implements TypedEventBroadcaster<EmitEvents>
{
constructor(
@@ -26,7 +26,7 @@ export class BroadcastOperator<EmitEvents extends EventsMap>
* @return a new BroadcastOperator instance
* @public
*/
public to(room: Room | Room[]): BroadcastOperator<EmitEvents> {
public to(room: Room | Room[]): BroadcastOperator<EmitEvents, SocketData> {
const rooms = new Set(this.rooms);
if (Array.isArray(room)) {
room.forEach((r) => rooms.add(r));
@@ -48,7 +48,7 @@ export class BroadcastOperator<EmitEvents extends EventsMap>
* @return a new BroadcastOperator instance
* @public
*/
public in(room: Room | Room[]): BroadcastOperator<EmitEvents> {
public in(room: Room | Room[]): BroadcastOperator<EmitEvents, SocketData> {
return this.to(room);
}
@@ -59,7 +59,9 @@ export class BroadcastOperator<EmitEvents extends EventsMap>
* @return a new BroadcastOperator instance
* @public
*/
public except(room: Room | Room[]): BroadcastOperator<EmitEvents> {
public except(
room: Room | Room[]
): BroadcastOperator<EmitEvents, SocketData> {
const exceptRooms = new Set(this.exceptRooms);
if (Array.isArray(room)) {
room.forEach((r) => exceptRooms.add(r));
@@ -81,7 +83,9 @@ export class BroadcastOperator<EmitEvents extends EventsMap>
* @return a new BroadcastOperator instance
* @public
*/
public compress(compress: boolean): BroadcastOperator<EmitEvents> {
public compress(
compress: boolean
): BroadcastOperator<EmitEvents, SocketData> {
const flags = Object.assign({}, this.flags, { compress });
return new BroadcastOperator(
this.adapter,
@@ -99,7 +103,7 @@ export class BroadcastOperator<EmitEvents extends EventsMap>
* @return a new BroadcastOperator instance
* @public
*/
public get volatile(): BroadcastOperator<EmitEvents> {
public get volatile(): BroadcastOperator<EmitEvents, SocketData> {
const flags = Object.assign({}, this.flags, { volatile: true });
return new BroadcastOperator(
this.adapter,
@@ -115,7 +119,7 @@ export class BroadcastOperator<EmitEvents extends EventsMap>
* @return a new BroadcastOperator instance
* @public
*/
public get local(): BroadcastOperator<EmitEvents> {
public get local(): BroadcastOperator<EmitEvents, SocketData> {
const flags = Object.assign({}, this.flags, { local: true });
return new BroadcastOperator(
this.adapter,
@@ -177,7 +181,9 @@ export class BroadcastOperator<EmitEvents extends EventsMap>
*
* @public
*/
public fetchSockets(): Promise<RemoteSocket<EmitEvents>[]> {
public fetchSockets<SocketData = any>(): Promise<
RemoteSocket<EmitEvents, SocketData>[]
> {
return this.adapter
.fetchSockets({
rooms: this.rooms,
@@ -187,9 +193,12 @@ export class BroadcastOperator<EmitEvents extends EventsMap>
return sockets.map((socket) => {
if (socket instanceof Socket) {
// FIXME the TypeScript compiler complains about missing private properties
return socket as unknown as RemoteSocket<EmitEvents>;
return socket as unknown as RemoteSocket<EmitEvents, SocketData>;
} else {
return new RemoteSocket(this.adapter, socket as SocketDetails);
return new RemoteSocket(
this.adapter,
socket as SocketDetails<SocketData>
);
}
});
});
@@ -247,27 +256,27 @@ export class BroadcastOperator<EmitEvents extends EventsMap>
/**
* Format of the data when the Socket instance exists on another Socket.IO server
*/
interface SocketDetails {
interface SocketDetails<SocketData> {
id: SocketId;
handshake: Handshake;
rooms: Room[];
data: any;
data: SocketData;
}
/**
* Expose of subset of the attributes and methods of the Socket class
*/
export class RemoteSocket<EmitEvents extends EventsMap>
export class RemoteSocket<EmitEvents extends EventsMap, SocketData>
implements TypedEventBroadcaster<EmitEvents>
{
public readonly id: SocketId;
public readonly handshake: Handshake;
public readonly rooms: Set<Room>;
public readonly data: any;
public readonly data: SocketData;
private readonly operator: BroadcastOperator<EmitEvents>;
private readonly operator: BroadcastOperator<EmitEvents, SocketData>;
constructor(adapter: Adapter, details: SocketDetails) {
constructor(adapter: Adapter, details: SocketDetails<SocketData>) {
this.id = details.id;
this.handshake = details.handshake;
this.rooms = new Set(details.rooms);

View File

@@ -112,11 +112,13 @@ export class Server<
/**
* @private
*/
_nsps: Map<string, Namespace<ListenEvents, EmitEvents, ServerSideEvents>> =
new Map();
_nsps: Map<
string,
Namespace<ListenEvents, EmitEvents, ServerSideEvents, SocketData>
> = new Map();
private parentNsps: Map<
ParentNspNameMatchFn,
ParentNamespace<ListenEvents, EmitEvents, ServerSideEvents>
ParentNamespace<ListenEvents, EmitEvents, ServerSideEvents, SocketData>
> = new Map();
private _adapter?: AdapterConstructor;
private _serveClient: boolean;
@@ -197,7 +199,9 @@ export class Server<
name: string,
auth: { [key: string]: any },
fn: (
nsp: Namespace<ListenEvents, EmitEvents, ServerSideEvents> | false
nsp:
| Namespace<ListenEvents, EmitEvents, ServerSideEvents, SocketData>
| false
) => void
): void {
if (this.parentNsps.size === 0) return fn(false);
@@ -579,7 +583,7 @@ export class Server<
fn?: (
socket: Socket<ListenEvents, EmitEvents, ServerSideEvents, SocketData>
) => void
): Namespace<ListenEvents, EmitEvents, ServerSideEvents> {
): Namespace<ListenEvents, EmitEvents, ServerSideEvents, SocketData> {
if (typeof name === "function" || name instanceof RegExp) {
const parentNsp = new ParentNamespace(this);
debug("initializing parent namespace %s", parentNsp.name);
@@ -660,7 +664,7 @@ export class Server<
* @return self
* @public
*/
public to(room: Room | Room[]): BroadcastOperator<EmitEvents> {
public to(room: Room | Room[]): BroadcastOperator<EmitEvents, SocketData> {
return this.sockets.to(room);
}
@@ -671,7 +675,7 @@ export class Server<
* @return self
* @public
*/
public in(room: Room | Room[]): BroadcastOperator<EmitEvents> {
public in(room: Room | Room[]): BroadcastOperator<EmitEvents, SocketData> {
return this.sockets.in(room);
}
@@ -682,7 +686,9 @@ export class Server<
* @return self
* @public
*/
public except(name: Room | Room[]): BroadcastOperator<EmitEvents> {
public except(
name: Room | Room[]
): BroadcastOperator<EmitEvents, SocketData> {
return this.sockets.except(name);
}
@@ -738,7 +744,9 @@ export class Server<
* @return self
* @public
*/
public compress(compress: boolean): BroadcastOperator<EmitEvents> {
public compress(
compress: boolean
): BroadcastOperator<EmitEvents, SocketData> {
return this.sockets.compress(compress);
}
@@ -750,7 +758,7 @@ export class Server<
* @return self
* @public
*/
public get volatile(): BroadcastOperator<EmitEvents> {
public get volatile(): BroadcastOperator<EmitEvents, SocketData> {
return this.sockets.volatile;
}
@@ -760,7 +768,7 @@ export class Server<
* @return self
* @public
*/
public get local(): BroadcastOperator<EmitEvents> {
public get local(): BroadcastOperator<EmitEvents, SocketData> {
return this.sockets.local;
}
@@ -769,7 +777,7 @@ export class Server<
*
* @public
*/
public fetchSockets(): Promise<RemoteSocket<EmitEvents>[]> {
public fetchSockets(): Promise<RemoteSocket<EmitEvents, SocketData>[]> {
return this.sockets.fetchSockets();
}
@@ -826,3 +834,4 @@ module.exports.Namespace = Namespace;
module.exports.Socket = Socket;
export { Socket, ServerOptions, Namespace, BroadcastOperator, RemoteSocket };
export { Event } from "./socket";

View File

@@ -175,7 +175,7 @@ export class Namespace<
* @return self
* @public
*/
public to(room: Room | Room[]): BroadcastOperator<EmitEvents> {
public to(room: Room | Room[]): BroadcastOperator<EmitEvents, SocketData> {
return new BroadcastOperator(this.adapter).to(room);
}
@@ -186,7 +186,7 @@ export class Namespace<
* @return self
* @public
*/
public in(room: Room | Room[]): BroadcastOperator<EmitEvents> {
public in(room: Room | Room[]): BroadcastOperator<EmitEvents, SocketData> {
return new BroadcastOperator(this.adapter).in(room);
}
@@ -197,7 +197,9 @@ export class Namespace<
* @return self
* @public
*/
public except(room: Room | Room[]): BroadcastOperator<EmitEvents> {
public except(
room: Room | Room[]
): BroadcastOperator<EmitEvents, SocketData> {
return new BroadcastOperator(this.adapter).except(room);
}
@@ -274,7 +276,10 @@ export class Namespace<
ev: Ev,
...args: EventParams<EmitEvents, Ev>
): boolean {
return new BroadcastOperator<EmitEvents>(this.adapter).emit(ev, ...args);
return new BroadcastOperator<EmitEvents, SocketData>(this.adapter).emit(
ev,
...args
);
}
/**
@@ -346,7 +351,9 @@ export class Namespace<
* @return self
* @public
*/
public compress(compress: boolean): BroadcastOperator<EmitEvents> {
public compress(
compress: boolean
): BroadcastOperator<EmitEvents, SocketData> {
return new BroadcastOperator(this.adapter).compress(compress);
}
@@ -358,7 +365,7 @@ export class Namespace<
* @return self
* @public
*/
public get volatile(): BroadcastOperator<EmitEvents> {
public get volatile(): BroadcastOperator<EmitEvents, SocketData> {
return new BroadcastOperator(this.adapter).volatile;
}
@@ -368,7 +375,7 @@ export class Namespace<
* @return self
* @public
*/
public get local(): BroadcastOperator<EmitEvents> {
public get local(): BroadcastOperator<EmitEvents, SocketData> {
return new BroadcastOperator(this.adapter).local;
}
@@ -377,7 +384,7 @@ export class Namespace<
*
* @public
*/
public fetchSockets(): Promise<RemoteSocket<EmitEvents>[]> {
public fetchSockets(): Promise<RemoteSocket<EmitEvents, SocketData>[]> {
return new BroadcastOperator(this.adapter).fetchSockets();
}

View File

@@ -1,5 +1,5 @@
import { Namespace } from "./namespace";
import type { Server } from "./index";
import type { Server, RemoteSocket } from "./index";
import type {
EventParams,
EventNames,
@@ -64,4 +64,13 @@ export class ParentNamespace<
this.server._nsps.set(name, namespace);
return namespace;
}
fetchSockets(): Promise<RemoteSocket<EmitEvents, SocketData>[]> {
// note: we could make the fetchSockets() method work for dynamic namespaces created with a regex (by sending the
// regex to the other Socket.IO servers, and returning the sockets of each matching namespace for example), but
// the behavior for namespaces created with a function is less clear
// note²: we cannot loop over each children namespace, because with multiple Socket.IO servers, a given namespace
// may exist on one node but not exist on another (since it is created upon client connection)
throw new Error("fetchSockets() is not supported on parent namespaces");
}
}

View File

@@ -107,7 +107,10 @@ export interface Handshake {
auth: { [key: string]: any };
}
type Event = [eventName: string, ...args: any[]];
/**
* `[eventName, ...args]`
*/
export type Event = [string, ...any[]];
export class Socket<
ListenEvents extends EventsMap = DefaultEventsMap,
@@ -251,7 +254,7 @@ export class Socket<
* @return self
* @public
*/
public to(room: Room | Room[]): BroadcastOperator<EmitEvents> {
public to(room: Room | Room[]): BroadcastOperator<EmitEvents, SocketData> {
return this.newBroadcastOperator().to(room);
}
@@ -262,7 +265,7 @@ export class Socket<
* @return self
* @public
*/
public in(room: Room | Room[]): BroadcastOperator<EmitEvents> {
public in(room: Room | Room[]): BroadcastOperator<EmitEvents, SocketData> {
return this.newBroadcastOperator().in(room);
}
@@ -273,7 +276,9 @@ export class Socket<
* @return self
* @public
*/
public except(room: Room | Room[]): BroadcastOperator<EmitEvents> {
public except(
room: Room | Room[]
): BroadcastOperator<EmitEvents, SocketData> {
return this.newBroadcastOperator().except(room);
}
@@ -577,7 +582,7 @@ export class Socket<
* @return {Socket} self
* @public
*/
public get broadcast(): BroadcastOperator<EmitEvents> {
public get broadcast(): BroadcastOperator<EmitEvents, SocketData> {
return this.newBroadcastOperator();
}
@@ -587,7 +592,7 @@ export class Socket<
* @return {Socket} self
* @public
*/
public get local(): BroadcastOperator<EmitEvents> {
public get local(): BroadcastOperator<EmitEvents, SocketData> {
return this.newBroadcastOperator().local;
}
@@ -764,7 +769,7 @@ export class Socket<
return this._anyListeners || [];
}
private newBroadcastOperator(): BroadcastOperator<EmitEvents> {
private newBroadcastOperator(): BroadcastOperator<EmitEvents, SocketData> {
const flags = Object.assign({}, this.flags);
this.flags = {};
return new BroadcastOperator(

169
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "socket.io",
"version": "4.4.0",
"version": "4.4.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -442,9 +442,9 @@
"dev": true
},
"@types/node": {
"version": "16.11.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz",
"integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw=="
"version": "17.0.12",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.12.tgz",
"integrity": "sha512-4YpbAsnJXWYK/fpTVFlMIcUIho2AYCi4wg5aNPrG1ng7fn/1/RZfCIpRCiBX+12RVa34RluilnvCqD+g3KiSiA=="
},
"@types/normalize-package-data": {
"version": "2.4.0",
@@ -507,9 +507,9 @@
}
},
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true
},
"ansi-styles": {
@@ -684,31 +684,6 @@
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
},
"dependencies": {
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"string-width": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.0"
}
}
}
},
"color-convert": {
@@ -888,9 +863,9 @@
"dev": true
},
"engine.io": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.0.tgz",
"integrity": "sha512-ErhZOVu2xweCjEfYcTdkCnEYUiZgkAcBBAhW4jbIvNG8SLU3orAqoJCiytZjYF7eTpVmmCrLDjLIEaPlUAs1uw==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.1.2.tgz",
"integrity": "sha512-v/7eGHxPvO2AWsksyx2PUsQvBafuvqs0jJJQ0FdmJG1b9qIvgSbqDRGwNhfk2XHaTTbTXiC4quRE8Q9nRjsrQQ==",
"requires": {
"@types/cookie": "^0.4.1",
"@types/cors": "^2.8.12",
@@ -1614,9 +1589,9 @@
}
},
"lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"lodash._baseassign": {
@@ -1899,6 +1874,23 @@
"kind-of": "^6.0.3"
}
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"requires": {
"minimist": "0.0.8"
},
"dependencies": {
"minimist": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
}
}
},
"mocha": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz",
@@ -1948,21 +1940,6 @@
"integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
"dev": true
},
"minimist": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"requires": {
"minimist": "0.0.8"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -2186,9 +2163,9 @@
"dev": true
},
"path-parse": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
"dev": true
},
"path-type": {
@@ -2436,9 +2413,9 @@
"integrity": "sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ=="
},
"socket.io-client": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.4.0.tgz",
"integrity": "sha512-g7riSEJXi7qCFImPow98oT8X++MSsHz6MMFRXkWNJ6uEROSHOa3kxdrsYWMq85dO+09CFMkcqlpjvbVXQl4z6g==",
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.4.1.tgz",
"integrity": "sha512-N5C/L5fLNha5Ojd7Yeb/puKcPWWcoB/A09fEjjNsg91EDVr5twk/OEyO6VT9dlLSUNY85NpW6KBhVMvaLKQ3vQ==",
"dev": true,
"requires": {
"@socket.io/component-emitter": "~3.0.0",
@@ -2490,9 +2467,9 @@
}
},
"engine.io-client": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.1.tgz",
"integrity": "sha512-oVu9kBkGbcggulyVF0kz6BV3ganqUeqXvD79WOFKa+11oK692w1NyFkuEj4xrkFRpZhn92QOqTk4RQq5LiBXbQ==",
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.2.tgz",
"integrity": "sha512-QEqIp+gJ/kMHeUun7f5Vv3bteRHppHH/FMBQX/esFj/fuYfjyUKWGMo3VCvIP/V8bE9KcjHmRZrhIz2Z9oNsDA==",
"dev": true,
"requires": {
"component-emitter": "~1.3.0",
@@ -2504,7 +2481,7 @@
"parseqs": "0.0.6",
"parseuri": "0.0.6",
"ws": "~7.4.2",
"xmlhttprequest-ssl": "~1.5.4",
"xmlhttprequest-ssl": "~1.6.2",
"yeast": "0.1.2"
}
},
@@ -2915,29 +2892,6 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"string-width": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.0"
}
}
}
},
@@ -2960,21 +2914,21 @@
}
},
"ws": {
"version": "7.4.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz",
"integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==",
"version": "7.4.6",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
"dev": true
},
"xmlhttprequest-ssl": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
"integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=",
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz",
"integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==",
"dev": true
},
"y18n": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
"dev": true
},
"yallist": {
@@ -3000,31 +2954,6 @@
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
},
"dependencies": {
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"string-width": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
"integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.0"
}
}
}
},
"yargs-parser": {

View File

@@ -1,6 +1,6 @@
{
"name": "socket.io",
"version": "4.4.0",
"version": "4.4.1",
"description": "node.js realtime framework server",
"keywords": [
"realtime",
@@ -27,7 +27,8 @@
"main": "./dist/index.js",
"exports": {
"import": "./wrapper.mjs",
"require": "./dist/index.js"
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"types": "./dist/index.d.ts",
"license": "MIT",
@@ -48,7 +49,7 @@
"accepts": "~1.3.4",
"base64id": "~2.0.0",
"debug": "~4.3.2",
"engine.io": "~6.1.0",
"engine.io": "~6.1.2",
"socket.io-adapter": "~2.3.3",
"socket.io-parser": "~4.0.4"
},
@@ -59,7 +60,7 @@
"nyc": "^15.1.0",
"prettier": "^2.3.2",
"rimraf": "^3.0.2",
"socket.io-client": "4.4.0",
"socket.io-client": "4.4.1",
"socket.io-client-v2": "npm:socket.io-client@^2.4.0",
"superagent": "^6.1.0",
"supertest": "^6.1.6",

View File

@@ -1830,7 +1830,7 @@ describe("socket.io", () => {
reconnectionDelay: 100,
});
clientSocket.once("connect", () => {
srv.close(() => {
sio.close(() => {
clientSocket.io.on("reconnect", () => {
clientSocket.emit("ev", "payload");
});

View File

@@ -46,8 +46,10 @@ describe("socket.io with uWebSocket.js-based engine", () => {
});
const partialDone = createPartialDone(done, 4);
io.on("connection", partialDone);
io.of("/custom").on("connection", partialDone);
client.on("connect", partialDone);
clientWSOnly.on("connect", partialDone);
clientPollingOnly.on("connect", partialDone);
clientCustomNamespace.on("connect", partialDone);
});
afterEach(() => {