playsocketjs 1.0.0 → 1.0.2

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,17 @@ 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
+ console.log('Shutting down gracefully...');
138
+ server.stop();
139
+ process.exit(0);
140
+ }
141
+
142
+ // Handle both SIGINT (Ctrl+C) and SIGTERM (Docker stop)
143
+ process.on('SIGINT', shutdown);
144
+ process.on('SIGTERM', shutdown);
134
145
  ```
135
146
 
136
147
  ### With Express.js
@@ -145,9 +156,8 @@ const app = express();
145
156
  const httpServer = http.createServer(app);
146
157
 
147
158
  // Create PlaySocket server with your HTTP server
148
- // Uses a custom path here (which you'll likely want to do if used this way)
149
- const playSocketServer = new PlaySocketServer({
150
- port,
159
+ // You'll likely want to use a custom path in this scenario
160
+ const playSocketServer = new PlaySocketServer({
151
161
  server: httpServer,
152
162
  path: '/socket'
153
163
  });
@@ -156,6 +166,17 @@ const playSocketServer = new PlaySocketServer({
156
166
  httpServer.listen(port, () => {
157
167
  console.log('Server running on port 3000');
158
168
  });
169
+
170
+ // Gracefully disconnect all clients and close the server (optional)
171
+ function shutdown() {
172
+ console.log('Shutting down gracefully...');
173
+ server.stop();
174
+ process.exit(0);
175
+ }
176
+
177
+ // Handle both SIGINT (Ctrl+C) and SIGTERM (Docker stop)
178
+ process.on('SIGINT', shutdown);
179
+ process.on('SIGTERM', shutdown);
159
180
  ```
160
181
 
161
182
  ## API Reference
@@ -176,6 +197,7 @@ Creates a new PlaySocket Server instance with configuration options.
176
197
 
177
198
  ### Methods
178
199
 
200
+ - `stop`: Closes all active client connections, the websocket server and the underlying http server if it's standalone
179
201
  - `onEvent(event: string, callback: Function)`: Register a server-side event callback
180
202
 
181
203
  ##### Event types
@@ -403,6 +403,10 @@ class PlaySocket {
403
403
  if (this.#socket) {
404
404
  this.#socket.close();
405
405
  this.#socket = null;
406
+
407
+ // Trigger events
408
+ this.#triggerEvent("status", "Destroyed.");
409
+ this.#triggerEvent("instanceDestroyed");
406
410
  }
407
411
 
408
412
  // Reset state
@@ -412,9 +416,6 @@ class PlaySocket {
412
416
  this.#storage = {};
413
417
  this.#roomId = null;
414
418
  this.#connectionCount = 0;
415
-
416
- this.#triggerEvent("status", "Destroyed.");
417
- this.#triggerEvent("instanceDestroyed");
418
419
  }
419
420
 
420
421
  // 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
+ if (this.#heartbeatInterval) 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.0",
3
+ "version": "1.0.2",
4
4
  "description": "WebSocket wrapper for creating simple multiplayer systems with ease.",
5
5
  "module": "dist/playsocket-client.js",
6
6
  "exports": {