playsocketjs 5.2.1 → 5.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -282,6 +282,7 @@ new PlaySocketServer(options?: PlaySocketServerOptions)
282
282
  | `path` | `string` | No | "/" | WebSocket endpoint path. |
283
283
  | `server` | `http.Server` | No | - | Existing http server. |
284
284
  | `rateLimit` | `number` | No | 20 | Messages/second rate limit. |
285
+ | `maxPayload` | `number` | No | 6291456 | Max. size of a single incoming message in bytes. |
285
286
  | `debug` | `boolean` | No | false | Enable debug logging. |
286
287
  | `verifyClient` | `function` | No | - | Callback to verify connections before WebSocket upgrade. |
287
288
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playsocketjs",
3
- "version": "5.2.1",
3
+ "version": "5.3.1",
4
4
  "description": "WebSocket wrapper for creating simple multiplayer systems with ease.",
5
5
  "type": "module",
6
6
  "module": "./src/client/client.js",
@@ -88,10 +88,11 @@ export default class PlaySocketServer {
88
88
  * @param {string} [options.path='/'] - WebSocket endpoint path
89
89
  * @param {boolean} [options.debug=false] - Enable debug logging
90
90
  * @param {number} [options.rateLimit=20] - Maximum number of operations per second per client
91
+ * @param {number} [options.maxPayload=6291456] - Maximum size of a single incoming message in bytes
91
92
  * @param {import("ws").ServerOptions["verifyClient"]} [options.verifyClient] - Optional callback to verify client connections before upgrade. Receives (info, callback) where info contains { req, origin } and callback is (verified, code?, message?) => void
92
93
  */
93
94
  constructor(options = {}) {
94
- const { server, port = 3000, path = "/", debug = false, rateLimit = 20, verifyClient } = options;
95
+ const { server, port = 3000, path = "/", debug = false, rateLimit = 20, maxPayload = 6 * 1024 * 1024, verifyClient } = options;
95
96
 
96
97
  if (debug) this.#debug = true; // Enable extra logging
97
98
 
@@ -112,6 +113,7 @@ export default class PlaySocketServer {
112
113
  this.#wss = new WebSocketServer({
113
114
  server: this.#server,
114
115
  path,
116
+ maxPayload,
115
117
  ...(verifyClient && { verifyClient })
116
118
  });
117
119
 
@@ -211,9 +213,11 @@ export default class PlaySocketServer {
211
213
  }
212
214
 
213
215
  case "reconnect": {
214
- // If user is pending disconnect, respond (otherwise it's too late)
215
- const pd = this.#pendingDisconnects.get(data.id);
216
- if (pd && data.sessionToken) {
216
+ // If user is pending disconnect or still on a dropped connection, respond (otherwise it's too late)
217
+ const pendingDisconnect = this.#pendingDisconnects.get(data.id);
218
+ const staleSocket = this.#clients.get(data.id); // Client requests reconnect even though the server thinks they are still connected
219
+
220
+ if ((pendingDisconnect || staleSocket) && data.sessionToken) {
217
221
  if (data.sessionToken !== this.#clientTokens.get(data.id)) {
218
222
  ws.send(encode({
219
223
  type: "reconnection_failed",
@@ -221,9 +225,15 @@ export default class PlaySocketServer {
221
225
  }), { binary: true });
222
226
  return;
223
227
  }
224
- clearTimeout(pd.timeout);
228
+ clearTimeout(pendingDisconnect?.timeout);
225
229
  this.#pendingDisconnects.delete(data.id);
226
230
 
231
+ // Only terminate if it's a different connection sending the reconnect
232
+ if (staleSocket && staleSocket !== ws) {
233
+ staleSocket.clientId = null; // So the close skips disconnection (handleDisconnection exits if the client ID is falsy)
234
+ staleSocket.terminate();
235
+ }
236
+
227
237
  // Re-assign old client ID to the new ws connection
228
238
  ws.clientId = data.id;
229
239
  this.#clients.set(data.id, ws);
@@ -414,9 +424,7 @@ export default class PlaySocketServer {
414
424
  * @returns {string} Token
415
425
  */
416
426
  #generateSessionToken() {
417
- let token = "";
418
- for (let i = 0; i < 16; i++) token += Math.floor(Math.random() * 16).toString(16);
419
- return token;
427
+ return crypto.randomUUID();
420
428
  }
421
429
 
422
430
  /**
@@ -9,7 +9,7 @@ export const HEARTBEAT_INTERVAL = 5000;
9
9
  /**
10
10
  * Library version, must match package.json
11
11
  */
12
- export const VERSION = "5.2.1";
12
+ export const VERSION = "5.3.1";
13
13
 
14
14
  /**
15
15
  * Logging prefixes
@@ -114,6 +114,7 @@ export default class PlaySocketServer {
114
114
  * @param {string} [options.path='/'] - WebSocket endpoint path
115
115
  * @param {boolean} [options.debug=false] - Enable debug logging
116
116
  * @param {number} [options.rateLimit=20] - Maximum number of operations per second per client
117
+ * @param {number} [options.maxPayload=6291456] - Maximum size of a single incoming message in bytes
117
118
  * @param {import("ws").ServerOptions["verifyClient"]} [options.verifyClient] - Optional callback to verify client connections before upgrade. Receives (info, callback) where info contains { req, origin } and callback is (verified, code?, message?) => void
118
119
  */
119
120
  constructor(options?: {
@@ -122,6 +123,7 @@ export default class PlaySocketServer {
122
123
  path?: string;
123
124
  debug?: boolean;
124
125
  rateLimit?: number;
126
+ maxPayload?: number;
125
127
  verifyClient?: import("ws").ServerOptions["verifyClient"];
126
128
  });
127
129
  /**
@@ -8,7 +8,7 @@ export declare const HEARTBEAT_INTERVAL = 5000;
8
8
  /**
9
9
  * Library version, must match package.json
10
10
  */
11
- export declare const VERSION = "5.2.1";
11
+ export declare const VERSION = "5.3.1";
12
12
  /**
13
13
  * Logging prefixes
14
14
  */