playsocketjs 1.0.1 → 1.0.3

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
@@ -131,6 +131,16 @@ const PlaySocketServer = require('playsocketjs/server');
131
131
 
132
132
  // Create and start the server
133
133
  const server = new PlaySocketServer();
134
+
135
+ // Gracefully disconnect all clients and close the server (optional)
136
+ function shutdown() {
137
+ server.stop();
138
+ process.exit(0);
139
+ }
140
+
141
+ // Handle both SIGINT (Ctrl+C) and SIGTERM (Docker stop)
142
+ process.on('SIGINT', shutdown);
143
+ process.on('SIGTERM', shutdown);
134
144
  ```
135
145
 
136
146
  ### With Express.js
@@ -155,6 +165,16 @@ const playSocketServer = new PlaySocketServer({
155
165
  httpServer.listen(port, () => {
156
166
  console.log('Server running on port 3000');
157
167
  });
168
+
169
+ // Gracefully disconnect all clients and close the server (optional)
170
+ function shutdown() {
171
+ server.stop();
172
+ process.exit(0);
173
+ }
174
+
175
+ // Handle both SIGINT (Ctrl+C) and SIGTERM (Docker stop)
176
+ process.on('SIGINT', shutdown);
177
+ process.on('SIGTERM', shutdown);
158
178
  ```
159
179
 
160
180
  ## API Reference
@@ -175,6 +195,7 @@ Creates a new PlaySocket Server instance with configuration options.
175
195
 
176
196
  ### Methods
177
197
 
198
+ - `stop`: Closes all active client connections, the websocket server and the underlying http server if it's standalone
178
199
  - `onEvent(event: string, callback: Function)`: Register a server-side event callback
179
200
 
180
201
  ##### Event types
@@ -4,7 +4,7 @@
4
4
 
5
5
  const ERROR_PREFIX = "PlaySocket error: ";
6
6
  const WARNING_PREFIX = "PlaySocket warning: ";
7
- const TIMEOUT_MS = 3000; // 3 second timeout for operations
7
+ const TIMEOUT_MS = 5000; // 5 second timeout for operations
8
8
 
9
9
  class PlaySocket {
10
10
  // Core properties
@@ -29,6 +29,9 @@ class PlaySocket {
29
29
  #pendingHost;
30
30
  #pendingInit;
31
31
 
32
+ // Timeouts or intervals
33
+ #reconnectTimeout;
34
+
32
35
  /**
33
36
  * Create a new PlaySocket instance
34
37
  * @param {string} id - Unique identifier for this client
@@ -227,10 +230,10 @@ class PlaySocket {
227
230
 
228
231
  // Handle socket close & attempt reconnect
229
232
  this.#socket.onclose = () => {
233
+ if (!this.#initialized) return;
230
234
  this.#triggerEvent("status", "Disconnected from server.");
231
235
 
232
- setTimeout(async () => {
233
- if (!this.#initialized || !this.#socket) return;
236
+ this.#reconnectTimeout = setTimeout(async () => {
234
237
  try {
235
238
  await this.#connect(); // Will set status to connected if successful
236
239
 
@@ -241,7 +244,6 @@ class PlaySocket {
241
244
  }
242
245
  } catch (error) {
243
246
  this.#triggerEvent("error", "WebSocket connection permanently closed: " + error);
244
- this.#socket = null;
245
247
  this.destroy();
246
248
  }
247
249
  }, 1000);
@@ -400,6 +402,8 @@ class PlaySocket {
400
402
  * Destroy the PlaySocket instance and disconnect
401
403
  */
402
404
  destroy() {
405
+ this.#initialized = false; // Set this immediately to prevent automatic reconnection
406
+
403
407
  if (this.#socket) {
404
408
  this.#socket.close();
405
409
  this.#socket = null;
@@ -410,12 +414,12 @@ class PlaySocket {
410
414
  }
411
415
 
412
416
  // Reset state
413
- this.#initialized = false;
414
417
  this.#isHost = false;
415
418
  this.#roomHost = null;
416
419
  this.#storage = {};
417
420
  this.#roomId = null;
418
421
  this.#connectionCount = 0;
422
+ clearTimeout(this.#reconnectTimeout);
419
423
  }
420
424
 
421
425
  // Public getters
@@ -21,12 +21,14 @@ function requireServer () {
21
21
  */
22
22
  class PlaySocketServer {
23
23
  #server;
24
+ #ownsServer = false;
24
25
  #wss;
25
26
  #clients = new Map(); // ClientId -> WebSocket instance
26
27
  #rooms = {};
27
28
  #clientRooms = new Map(); // ClientId -> RoomId
28
29
  #rateLimits = new Map(); // Rate limiting storage
29
30
  #callbacks = new Map();
31
+ #heartbeatInterval;
30
32
 
31
33
  /**
32
34
  * Create a new PlaySocketServer instance
@@ -42,6 +44,7 @@ function requireServer () {
42
44
  if (server) {
43
45
  this.#server = server; // Use provided HTTP server
44
46
  } else {
47
+ this.#ownsServer = true;
45
48
  this.#server = http.createServer(); // Create HTTP server and start it
46
49
  this.#server.listen(port, () => {
47
50
  console.log(`PlaySocket server running on port ${port}`);
@@ -56,11 +59,20 @@ function requireServer () {
56
59
 
57
60
  // Set up ws event handlers
58
61
  this.#wss.on('connection', ws => {
62
+ ws.isAlive = true;
63
+ ws.on('pong', () => { ws.isAlive = true; });
59
64
  ws.on('message', msg => this.#handleMessage(ws, msg));
60
65
  ws.on('close', () => this.#handleDisconnection(ws));
61
66
  });
62
67
 
63
- process.on('SIGINT', () => this.#stop()); // Graceful shutdown
68
+ // Start heartbeat
69
+ this.#heartbeatInterval = setInterval(() => {
70
+ this.#wss.clients.forEach(ws => {
71
+ if (!ws.isAlive) return ws.terminate();
72
+ ws.isAlive = false;
73
+ ws.ping();
74
+ });
75
+ }, 30000);
64
76
  }
65
77
 
66
78
  /**
@@ -320,16 +332,15 @@ function requireServer () {
320
332
  }
321
333
 
322
334
  /**
323
- * Stop the server
324
- * @private
335
+ * Close all client connections, then close the websocket and http server
325
336
  */
326
- #stop() {
337
+ stop() {
338
+ clearInterval(this.#heartbeatInterval);
327
339
  if (this.#wss) {
328
340
  this.#wss.clients.forEach(client => client.close());
329
- this.#wss.close(); // TODO necessary?
341
+ this.#wss.close();
330
342
  }
331
-
332
- if (this.#server) {
343
+ if (this.#server && this.#ownsServer) {
333
344
  this.#server.close(() => {
334
345
  console.log('PlaySocket server stopped');
335
346
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playsocketjs",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "WebSocket wrapper for creating simple multiplayer systems with ease.",
5
5
  "module": "dist/playsocket-client.js",
6
6
  "exports": {