uniwrtc 1.0.2 → 1.0.4

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
@@ -2,10 +2,12 @@
2
2
 
3
3
  A universal WebRTC signaling service that provides a simple and flexible WebSocket-based signaling server for WebRTC applications.
4
4
 
5
+ Available on npm: https://www.npmjs.com/package/uniwrtc
6
+
5
7
  ## Features
6
8
 
7
9
  - 🚀 **Simple WebSocket-based signaling** - Easy to integrate with any WebRTC application
8
- - 🏠 **Room-based architecture** - Support for multiple rooms with isolated peer groups
10
+ - 🏠 **Session-based architecture** - Support for multiple sessions with isolated peer groups
9
11
  - 🔌 **Flexible client library** - Ready-to-use JavaScript client for browser and Node.js
10
12
  - 📡 **Real-time messaging** - Efficient message routing between peers
11
13
  - 🔄 **Auto-reconnection** - Built-in reconnection logic for reliable connections
@@ -56,9 +58,9 @@ Open `demo.html` in your web browser to try the interactive demo:
56
58
  1. Start the server with `npm start` (local signaling at `ws://localhost:8080`), **or** use the deployed Workers endpoint `wss://signal.peer.ooo`.
57
59
  2. Open `demo.html` in your browser.
58
60
  3. Click "Connect" to connect to the signaling server.
59
- 4. Enter a room ID and click "Join Room".
61
+ 4. Enter a session ID and click "Join Session".
60
62
  5. Open another browser window/tab with the same demo page.
61
- 6. Join the same room to see peer connections in action and P2P data channels open.
63
+ 6. Join the same session to see peer connections in action and P2P data channels open.
62
64
 
63
65
  ## Usage
64
66
 
@@ -68,19 +70,19 @@ The signaling server accepts WebSocket connections and supports the following me
68
70
 
69
71
  #### Client → Server Messages
70
72
 
71
- **Join a room:**
73
+ **Join a session:**
72
74
  ```json
73
75
  {
74
76
  "type": "join",
75
- "roomId": "room-123"
77
+ "sessionId": "session-123"
76
78
  }
77
79
  ```
78
80
 
79
- **Leave a room:**
81
+ **Leave a session:**
80
82
  ```json
81
83
  {
82
84
  "type": "leave",
83
- "roomId": "room-123"
85
+ "sessionId": "session-123"
84
86
  }
85
87
  ```
86
88
 
@@ -90,7 +92,7 @@ The signaling server accepts WebSocket connections and supports the following me
90
92
  "type": "offer",
91
93
  "offer": { /* RTCSessionDescription */ },
92
94
  "targetId": "peer-client-id",
93
- "roomId": "room-123"
95
+ "sessionId": "session-123"
94
96
  }
95
97
  ```
96
98
 
@@ -100,7 +102,7 @@ The signaling server accepts WebSocket connections and supports the following me
100
102
  "type": "answer",
101
103
  "answer": { /* RTCSessionDescription */ },
102
104
  "targetId": "peer-client-id",
103
- "roomId": "room-123"
105
+ "sessionId": "session-123"
104
106
  }
105
107
  ```
106
108
 
@@ -110,7 +112,7 @@ The signaling server accepts WebSocket connections and supports the following me
110
112
  "type": "ice-candidate",
111
113
  "candidate": { /* RTCIceCandidate */ },
112
114
  "targetId": "peer-client-id",
113
- "roomId": "room-123"
115
+ "sessionId": "session-123"
114
116
  }
115
117
  ```
116
118
 
@@ -132,11 +134,11 @@ The signaling server accepts WebSocket connections and supports the following me
132
134
  }
133
135
  ```
134
136
 
135
- **Room joined confirmation:**
137
+ **Session joined confirmation:**
136
138
  ```json
137
139
  {
138
140
  "type": "joined",
139
- "roomId": "room-123",
141
+ "sessionId": "session-123",
140
142
  "clientId": "abc123",
141
143
  "clients": ["xyz789", "def456"]
142
144
  }
@@ -146,8 +148,8 @@ The signaling server accepts WebSocket connections and supports the following me
146
148
  ```json
147
149
  {
148
150
  "type": "peer-joined",
149
- "peerId": "new-peer-id",
150
- "clientId": "new-peer-id"
151
+ "sessionId": "session-123",
152
+ "peerId": "new-peer-id"
151
153
  }
152
154
  ```
153
155
 
@@ -155,8 +157,8 @@ The signaling server accepts WebSocket connections and supports the following me
155
157
  ```json
156
158
  {
157
159
  "type": "peer-left",
158
- "peerId": "departed-peer-id",
159
- "clientId": "departed-peer-id"
160
+ "sessionId": "session-123",
161
+ "peerId": "departed-peer-id"
160
162
  }
161
163
  ```
162
164
 
@@ -166,9 +168,8 @@ Use directly from npm:
166
168
  ```javascript
167
169
  // ESM
168
170
  import { UniWRTCClient } from 'uniwrtc/client-browser.js';
169
- // or CommonJS
170
- const { UniWRTCClient } = require('uniwrtc/client-browser.js');
171
- // For Node.js signaling client use 'uniwrtc/client.js'
171
+ // or CommonJS (Node)
172
+ const { UniWRTCClient } = require('uniwrtc/client.js');
172
173
  ```
173
174
 
174
175
  The `client.js` library provides a convenient wrapper for the signaling protocol:
@@ -183,7 +184,7 @@ client.on('connected', (data) => {
183
184
  });
184
185
 
185
186
  client.on('joined', (data) => {
186
- console.log('Joined room:', data.roomId);
187
+ console.log('Joined session:', data.sessionId);
187
188
  console.log('Existing peers:', data.clients);
188
189
  });
189
190
 
@@ -294,9 +295,9 @@ client.on('ice-candidate', async (data) => {
294
295
  }
295
296
  });
296
297
 
297
- // Connect and join room
298
+ // Connect and join session
298
299
  await client.connect();
299
- client.joinRoom('my-video-room');
300
+ client.joinSession('my-video-session');
300
301
  ```
301
302
 
302
303
  ## API Reference
@@ -318,8 +319,8 @@ new UniWRTCClient(serverUrl, options)
318
319
 
319
320
  - `connect()`: Connect to the signaling server (returns Promise)
320
321
  - `disconnect()`: Disconnect from the server
321
- - `joinRoom(roomId)`: Join a specific room
322
- - `leaveRoom()`: Leave the current room
322
+ - `joinSession(sessionId)`: Join a specific session
323
+ - `leaveSession()`: Leave the current session
323
324
  - `sendOffer(offer, targetId)`: Send a WebRTC offer
324
325
  - `sendAnswer(answer, targetId)`: Send a WebRTC answer
325
326
  - `sendIceCandidate(candidate, targetId)`: Send an ICE candidate
@@ -342,7 +343,7 @@ new UniWRTCClient(serverUrl, options)
342
343
 
343
344
  ## Health Check
344
345
 
345
- The server provides an HTTP health check endpoint:
346
+ The server provides an HTTP health check endpoint for monitoring:
346
347
 
347
348
  ```bash
348
349
  curl http://localhost:8080/health
@@ -358,12 +359,12 @@ Response:
358
359
 
359
360
  ## Architecture
360
361
 
361
- ### Room Management
362
+ ### Session Management
362
363
 
363
- - Each room is identified by a unique room ID (string)
364
- - Clients can join/leave rooms dynamically
365
- - Messages can be sent to specific peers or broadcast to all peers in a room
366
- - Empty rooms are automatically cleaned up
364
+ - Each session is identified by a unique session ID (string)
365
+ - Clients can join/leave sessions dynamically
366
+ - Messages can be sent to specific peers or broadcast to all peers in a session
367
+ - Empty sessions are automatically cleaned up
367
368
 
368
369
  ### Message Flow
369
370
 
package/client-browser.js CHANGED
@@ -8,7 +8,7 @@ class UniWRTCClient {
8
8
  this.serverUrl = serverUrl;
9
9
  this.ws = null;
10
10
  this.clientId = null;
11
- this.roomId = null;
11
+ this.sessionId = null;
12
12
  this.peers = new Map();
13
13
  this._connectedOnce = false;
14
14
  this.options = {
@@ -93,24 +93,26 @@ class UniWRTCClient {
93
93
  }
94
94
  }
95
95
 
96
- joinRoom(roomId) {
97
- // Prevent duplicate join calls for the same room
98
- if (this.roomId === roomId) return;
99
- this.roomId = roomId;
96
+ joinSession(sessionId) {
97
+ // Prevent duplicate join calls for the same session
98
+ if (this.sessionId === sessionId) return;
99
+ this.sessionId = sessionId;
100
+
101
+ // Send join message
100
102
  this.send({
101
103
  type: 'join',
102
- roomId: roomId,
104
+ sessionId: sessionId,
103
105
  peerId: this.clientId
104
106
  });
105
107
  }
106
108
 
107
- leaveRoom() {
108
- if (this.roomId) {
109
+ leaveSession() {
110
+ if (this.sessionId) {
109
111
  this.send({
110
112
  type: 'leave',
111
- roomId: this.roomId
113
+ sessionId: this.sessionId
112
114
  });
113
- this.roomId = null;
115
+ this.sessionId = null;
114
116
  }
115
117
  }
116
118
 
@@ -123,29 +125,32 @@ class UniWRTCClient {
123
125
  }
124
126
 
125
127
  sendOffer(offer, targetId) {
128
+ console.log(`[Client] Sending offer to ${targetId}`);
126
129
  this.send({
127
130
  type: 'offer',
128
131
  offer: offer,
129
132
  targetId: targetId,
130
- roomId: this.roomId
133
+ sessionId: this.sessionId
131
134
  });
132
135
  }
133
136
 
134
137
  sendAnswer(answer, targetId) {
138
+ console.log(`[Client] Sending answer to ${targetId}`);
135
139
  this.send({
136
140
  type: 'answer',
137
141
  answer: answer,
138
142
  targetId: targetId,
139
- roomId: this.roomId
143
+ sessionId: this.sessionId
140
144
  });
141
145
  }
142
146
 
143
147
  sendIceCandidate(candidate, targetId) {
148
+ console.log(`[Client] Sending ICE candidate to ${targetId}`);
144
149
  this.send({
145
150
  type: 'ice-candidate',
146
151
  candidate: candidate,
147
152
  targetId: targetId,
148
- roomId: this.roomId
153
+ sessionId: this.sessionId
149
154
  });
150
155
  }
151
156
 
@@ -187,9 +192,9 @@ class UniWRTCClient {
187
192
  console.log('[UniWRTC] If this helps, consider donating ❤️ → https://coff.ee/draederg');
188
193
  break;
189
194
  case 'joined':
190
- this.roomId = message.roomId;
195
+ this.sessionId = message.sessionId;
191
196
  this.emit('joined', {
192
- roomId: message.roomId,
197
+ sessionId: message.sessionId,
193
198
  peerId: message.peerId,
194
199
  clientId: message.clientId,
195
200
  clients: message.clients
@@ -197,27 +202,32 @@ class UniWRTCClient {
197
202
  break;
198
203
  case 'peer-joined':
199
204
  this.emit('peer-joined', {
205
+ sessionId: message.sessionId,
200
206
  peerId: message.peerId
201
207
  });
202
208
  break;
203
209
  case 'peer-left':
204
210
  this.emit('peer-left', {
211
+ sessionId: message.sessionId,
205
212
  peerId: message.peerId
206
213
  });
207
214
  break;
208
215
  case 'offer':
216
+ console.log(`[Client] Received offer from ${message.peerId}`);
209
217
  this.emit('offer', {
210
218
  peerId: message.peerId,
211
219
  offer: message.offer
212
220
  });
213
221
  break;
214
222
  case 'answer':
223
+ console.log(`[Client] Received answer from ${message.peerId}`);
215
224
  this.emit('answer', {
216
225
  peerId: message.peerId,
217
226
  answer: message.answer
218
227
  });
219
228
  break;
220
229
  case 'ice-candidate':
230
+ console.log(`[Client] Received ICE candidate from ${message.peerId}`);
221
231
  this.emit('ice-candidate', {
222
232
  peerId: message.peerId,
223
233
  candidate: message.candidate
@@ -237,7 +247,7 @@ class UniWRTCClient {
237
247
  this.emit('chat', {
238
248
  text: message.text,
239
249
  peerId: message.peerId,
240
- roomId: message.roomId
250
+ sessionId: message.sessionId
241
251
  });
242
252
  break;
243
253
  default:
package/client.js CHANGED
@@ -8,7 +8,7 @@ class UniWRTCClient {
8
8
  this.serverUrl = serverUrl;
9
9
  this.ws = null;
10
10
  this.clientId = null;
11
- this.roomId = null;
11
+ this.sessionId = null;
12
12
  this.peers = new Map();
13
13
  this.options = {
14
14
  autoReconnect: true,
@@ -85,21 +85,21 @@ class UniWRTCClient {
85
85
  }
86
86
  }
87
87
 
88
- joinRoom(roomId) {
89
- this.roomId = roomId;
88
+ joinSession(sessionId) {
89
+ this.sessionId = sessionId;
90
90
  this.send({
91
91
  type: 'join',
92
- roomId: roomId
92
+ sessionId: sessionId
93
93
  });
94
94
  }
95
95
 
96
- leaveRoom() {
97
- if (this.roomId) {
96
+ leaveSession() {
97
+ if (this.sessionId) {
98
98
  this.send({
99
99
  type: 'leave',
100
- roomId: this.roomId
100
+ sessionId: this.sessionId
101
101
  });
102
- this.roomId = null;
102
+ this.sessionId = null;
103
103
  }
104
104
  }
105
105
 
@@ -108,7 +108,7 @@ class UniWRTCClient {
108
108
  type: 'offer',
109
109
  offer: offer,
110
110
  targetId: targetId,
111
- roomId: this.roomId
111
+ sessionId: this.sessionId
112
112
  });
113
113
  }
114
114
 
@@ -117,7 +117,7 @@ class UniWRTCClient {
117
117
  type: 'answer',
118
118
  answer: answer,
119
119
  targetId: targetId,
120
- roomId: this.roomId
120
+ sessionId: this.sessionId
121
121
  });
122
122
  }
123
123
 
@@ -126,7 +126,7 @@ class UniWRTCClient {
126
126
  type: 'ice-candidate',
127
127
  candidate: candidate,
128
128
  targetId: targetId,
129
- roomId: this.roomId
129
+ sessionId: this.sessionId
130
130
  });
131
131
  }
132
132
 
@@ -152,18 +152,20 @@ class UniWRTCClient {
152
152
  break;
153
153
  case 'joined':
154
154
  this.emit('joined', {
155
- roomId: message.roomId,
155
+ sessionId: message.sessionId,
156
156
  clientId: message.clientId,
157
157
  clients: message.clients
158
158
  });
159
159
  break;
160
160
  case 'peer-joined':
161
161
  this.emit('peer-joined', {
162
+ sessionId: message.sessionId,
162
163
  peerId: message.peerId
163
164
  });
164
165
  break;
165
166
  case 'peer-left':
166
167
  this.emit('peer-left', {
168
+ sessionId: message.sessionId,
167
169
  peerId: message.peerId
168
170
  });
169
171
  break;
package/demo.html CHANGED
@@ -282,11 +282,11 @@
282
282
  </div>
283
283
 
284
284
  <div class="card">
285
- <h2>Room Status</h2>
285
+ <h2>Room / Session</h2>
286
286
 
287
287
  <div class="connection-controls" style="margin-bottom: 15px;">
288
- <input type="text" id="roomId" placeholder="Enter room ID" value="demo-room">
289
- <button class="btn-primary" id="joinBtn" onclick="joinRoom()" disabled>Join Room</button>
288
+ <input type="text" id="roomId" placeholder="Enter room/session ID" value="demo-room">
289
+ <button class="btn-primary" id="joinBtn" onclick="joinSession()" disabled>Join</button>
290
290
  </div>
291
291
 
292
292
  <div id="roomInfo">
@@ -314,7 +314,7 @@
314
314
  <p style="color: #999; text-align: center; padding: 20px;">Messages will appear here</p>
315
315
  </div>
316
316
  <div class="connection-controls" style="margin-bottom: 0;">
317
- <input type="text" id="chatMessage" placeholder="Type a message..." style="grid-column: 1 / -1;">
317
+ <input type="text" id="chatMessage" placeholder="Type a message..." style="grid-column: 1 / -1;" onkeypress="if(event.key === 'Enter') sendChatMessage()">
318
318
  <button class="btn-primary" onclick="sendChatMessage()" style="grid-column: 1 / -1;">Send Message</button>
319
319
  </div>
320
320
  </div> <div class="card">
@@ -430,18 +430,26 @@
430
430
  log('Connecting to signaling server...', 'info');
431
431
 
432
432
  const customPeerId = document.getElementById('customPeerId').value.trim();
433
- client = new UniWRTCClient(serverUrl, { customPeerId: customPeerId || null });
433
+
434
+ // For Cloudflare (signal.peer.ooo), append room param to URL
435
+ let finalUrl = serverUrl;
436
+ const roomId = document.getElementById('roomId').value;
437
+ if (serverUrl.includes('signal.peer.ooo') && roomId) {
438
+ finalUrl = serverUrl + (serverUrl.includes('?') ? '&' : '?') + `room=${roomId}`;
439
+ }
440
+
441
+ client = new UniWRTCClient(finalUrl, { customPeerId: customPeerId || null });
434
442
 
435
443
  client.on('connected', (data) => {
436
444
  log(`Connected with ID: ${data.clientId}`, 'success');
437
445
  updateStatus(true);
438
446
 
439
- // Auto-join room after connecting
447
+ // Auto-join session after connecting
440
448
  const roomId = document.getElementById('roomId').value;
441
449
  if (roomId) {
442
450
  setTimeout(() => {
443
- log(`Auto-joining room: ${roomId}...`, 'info');
444
- client.joinRoom(roomId);
451
+ log(`Auto-joining session: ${roomId}...`, 'info');
452
+ client.joinSession(roomId);
445
453
  }, 500);
446
454
  }
447
455
  });
@@ -455,15 +463,21 @@
455
463
  let knownPeers = [];
456
464
 
457
465
  client.on('joined', (data) => {
458
- log(`Joined room: ${data.roomId}`, 'success');
466
+ log(`Joined session: ${data.sessionId}`, 'success');
459
467
  knownPeers = data.clients || [];
460
468
  updatePeersList(knownPeers);
461
469
 
462
- // Update room info with dynamic peer count
463
- updateRoomInfo(data.roomId, client.clientId);
470
+ // Update session info with dynamic peer count
471
+ updateRoomInfo(data.sessionId, client.clientId);
464
472
  });
465
473
 
466
474
  client.on('peer-joined', (data) => {
475
+ // Only connect to peers in the same session (if we have one set)
476
+ if (client.sessionId && data.sessionId !== client.sessionId) {
477
+ log(`Ignoring peer from different session: ${data.peerId}`, 'warning');
478
+ return;
479
+ }
480
+
467
481
  log(`Peer joined: ${data.peerId}`, 'success');
468
482
  // Add to known peers if not already there
469
483
  if (data.peerId && !knownPeers.includes(data.peerId)) {
@@ -471,8 +485,8 @@
471
485
  updatePeersList(knownPeers);
472
486
  }
473
487
 
474
- // Update room info with new peer count
475
- updateRoomInfo(client.roomId, client.clientId);
488
+ // Update session info with new peer count
489
+ updateRoomInfo(data.sessionId, client.clientId);
476
490
 
477
491
  // Auto-initiate P2P connection
478
492
  setTimeout(() => {
@@ -481,14 +495,19 @@
481
495
  });
482
496
 
483
497
  client.on('peer-left', (data) => {
498
+ // Only process if from current session (if we have one set)
499
+ if (client.sessionId && data.sessionId !== client.sessionId) {
500
+ return;
501
+ }
502
+
484
503
  const peerId = data.peerId;
485
504
  log(`Peer left: ${peerId}`, 'warning');
486
505
  // Remove from known peers
487
506
  knownPeers = knownPeers.filter(id => id !== peerId);
488
507
  updatePeersList(knownPeers);
489
508
 
490
- // Update room info with new peer count
491
- updateRoomInfo(client.roomId, client.clientId);
509
+ // Update session info with new peer count
510
+ updateRoomInfo(data.sessionId, client.clientId);
492
511
 
493
512
  // Close peer connection
494
513
  const pc = peerConnections.get(peerId);
@@ -580,8 +599,8 @@
580
599
  return;
581
600
  }
582
601
 
583
- if (!client || !client.roomId) {
584
- log('Not connected to a room', 'error');
602
+ if (!client || !client.sessionId) {
603
+ log('Not connected to a session', 'error');
585
604
  return;
586
605
  }
587
606
 
@@ -590,10 +609,10 @@
590
609
  document.getElementById('manualPeerId').value = '';
591
610
  }
592
611
 
593
- function joinRoom() {
594
- const roomId = document.getElementById('roomId').value;
612
+ function joinSession() {
613
+ const sessionId = document.getElementById('roomId').value;
595
614
 
596
- if (!roomId) {
615
+ if (!sessionId) {
597
616
  log('Please enter a room ID', 'error');
598
617
  return;
599
618
  }
@@ -603,8 +622,8 @@
603
622
  return;
604
623
  }
605
624
 
606
- log(`Joining room: ${roomId}...`, 'info');
607
- client.joinRoom(roomId);
625
+ log(`Joining session: ${sessionId}...`, 'info');
626
+ client.joinSession(sessionId);
608
627
  }
609
628
 
610
629
  function listRooms() {
@@ -619,12 +638,15 @@
619
638
 
620
639
  async function createPeerConnection(peerId, initiator = false) {
621
640
  if (peerConnections.has(peerId)) {
641
+ log(`Peer connection already exists for ${peerId.substring(0, 6)}`, 'info');
622
642
  return peerConnections.get(peerId);
623
643
  }
624
644
 
625
645
  // Determine who should initiate based on peer IDs (lexicographic comparison)
626
646
  // Only the peer with smaller ID creates the offer
627
647
  const shouldInitiate = client.clientId < peerId;
648
+
649
+ log(`Creating peer connection with ${peerId.substring(0, 6)} (shouldInitiate: ${shouldInitiate})`, 'info');
628
650
 
629
651
  const pc = new RTCPeerConnection({
630
652
  iceServers: [
@@ -640,6 +662,7 @@
640
662
  };
641
663
 
642
664
  pc.ondatachannel = (event) => {
665
+ log(`Received data channel from ${peerId.substring(0, 6)}`, 'info');
643
666
  setupDataChannel(peerId, event.channel);
644
667
  };
645
668
 
@@ -651,6 +674,8 @@
651
674
  await pc.setLocalDescription(offer);
652
675
  client.sendOffer(offer, peerId);
653
676
  log(`Sent offer to ${peerId.substring(0, 6)}...`, 'success');
677
+ } else {
678
+ log(`Waiting for offer from ${peerId.substring(0, 6)}...`, 'info');
654
679
  }
655
680
 
656
681
  peerConnections.set(peerId, pc);
@@ -660,7 +685,6 @@
660
685
  function setupDataChannel(peerId, dataChannel) {
661
686
  dataChannel.onopen = () => {
662
687
  log(`Data channel open with ${peerId.substring(0, 6)}...`, 'success');
663
- dataChannels.set(peerId, dataChannel);
664
688
  };
665
689
 
666
690
  dataChannel.onmessage = (event) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uniwrtc",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "A universal WebRTC signaling service",
5
5
  "main": "server.js",
6
6
  "scripts": {
package/server.js CHANGED
@@ -54,9 +54,12 @@ function log(message, data = '') {
54
54
  console.log(`[${timestamp}] ${message}`, data);
55
55
  }
56
56
 
57
- function broadcastToRoom(roomId, message, excludeClient = null) {
58
- const room = rooms.get(roomId);
59
- if (!room) return;
57
+ function broadcastToRoom(sessionId, message, excludeClient = null) {
58
+ const room = rooms.get(sessionId);
59
+ if (!room) {
60
+ log(`WARNING: Attempted to broadcast to non-existent session: ${sessionId}`);
61
+ return;
62
+ }
60
63
 
61
64
  room.clients.forEach(client => {
62
65
  if (client !== excludeClient && client.readyState === WebSocket.OPEN) {
@@ -164,33 +167,33 @@ function handleSetId(ws, message) {
164
167
  }
165
168
 
166
169
  function handleJoin(ws, message) {
167
- const { roomId } = message;
170
+ const { sessionId } = message;
168
171
 
169
- if (!roomId) {
170
- sendToClient(ws, { type: 'error', message: 'Room ID is required' });
172
+ if (!sessionId) {
173
+ sendToClient(ws, { type: 'error', message: 'Session ID is required' });
171
174
  return;
172
175
  }
173
176
 
174
- // Leave current room if in one
177
+ // Leave current session if in one
175
178
  if (ws.room) {
176
- handleLeave(ws, { roomId: ws.room });
179
+ handleLeave(ws, { sessionId: ws.room });
177
180
  }
178
181
 
179
- // Create room if it doesn't exist
180
- if (!rooms.has(roomId)) {
181
- rooms.set(roomId, {
182
- id: roomId,
182
+ // Create session if it doesn't exist
183
+ if (!rooms.has(sessionId)) {
184
+ rooms.set(sessionId, {
185
+ id: sessionId,
183
186
  clients: new Set(),
184
187
  createdAt: Date.now()
185
188
  });
186
- log('Room created:', roomId);
189
+ log('Session created:', sessionId);
187
190
  }
188
191
 
189
- const room = rooms.get(roomId);
192
+ const room = rooms.get(sessionId);
190
193
  room.clients.add(ws);
191
- ws.room = roomId;
194
+ ws.room = sessionId;
192
195
 
193
- log(`Client ${ws.clientId} joined room ${roomId}`);
196
+ log(`Client ${ws.clientId} joined session ${sessionId}`);
194
197
 
195
198
  // Get list of existing clients in the room
196
199
  const existingClients = Array.from(room.clients)
@@ -200,50 +203,52 @@ function handleJoin(ws, message) {
200
203
  // Notify the joining client
201
204
  sendToClient(ws, {
202
205
  type: 'joined',
203
- roomId: roomId,
206
+ sessionId: sessionId,
204
207
  clientId: ws.clientId,
205
208
  clients: existingClients
206
209
  });
207
210
 
208
- // Notify other clients in the room
209
- broadcastToRoom(roomId, {
211
+ // Notify other clients in the session
212
+ broadcastToRoom(sessionId, {
210
213
  type: 'peer-joined',
214
+ sessionId: sessionId,
211
215
  peerId: ws.clientId
212
216
  }, ws);
213
217
  }
214
218
 
215
219
  function handleLeave(ws, message) {
216
- const { roomId } = message;
220
+ const { sessionId } = message;
217
221
 
218
- if (!roomId || !rooms.has(roomId)) {
222
+ if (!sessionId || !rooms.has(sessionId)) {
219
223
  return;
220
224
  }
221
225
 
222
- const room = rooms.get(roomId);
226
+ const room = rooms.get(sessionId);
223
227
  room.clients.delete(ws);
224
228
 
225
- log(`Client ${ws.clientId} left room ${roomId}`);
229
+ log(`Client ${ws.clientId} left session ${sessionId}`);
226
230
 
227
231
  // Notify other clients
228
- broadcastToRoom(roomId, {
232
+ broadcastToRoom(sessionId, {
229
233
  type: 'peer-left',
234
+ sessionId: sessionId,
230
235
  peerId: ws.clientId
231
236
  });
232
237
 
233
- // Clean up empty rooms
238
+ // Clean up empty sessions
234
239
  if (room.clients.size === 0) {
235
- rooms.delete(roomId);
236
- log('Room deleted:', roomId);
240
+ rooms.delete(sessionId);
241
+ log('Session deleted:', sessionId);
237
242
  }
238
243
 
239
244
  ws.room = null;
240
245
  }
241
246
 
242
247
  function handleSignaling(ws, message) {
243
- const { targetId, roomId } = message;
248
+ const { targetId, sessionId } = message;
244
249
 
245
250
  if (!ws.room) {
246
- sendToClient(ws, { type: 'error', message: 'Not in a room' });
251
+ sendToClient(ws, { type: 'error', message: 'Not in a session' });
247
252
  return;
248
253
  }
249
254
 
@@ -272,29 +277,29 @@ function handleSignaling(ws, message) {
272
277
  }
273
278
 
274
279
  function handleChat(ws, message) {
275
- const { roomId, text } = message;
280
+ const { sessionId, text } = message;
276
281
 
277
- if (!roomId || !text) {
278
- sendToClient(ws, { type: 'error', message: 'Room ID and text are required' });
282
+ if (!sessionId || !text) {
283
+ sendToClient(ws, { type: 'error', message: 'Session ID and text are required' });
279
284
  return;
280
285
  }
281
286
 
282
- log(`Chat message in room ${roomId}: ${text.substring(0, 50)}`);
287
+ log(`Chat message in session ${sessionId}: ${text.substring(0, 50)}`);
283
288
 
284
- const room = rooms.get(roomId);
289
+ const room = rooms.get(sessionId);
285
290
  if (!room) {
286
- sendToClient(ws, { type: 'error', message: 'Room not found' });
291
+ sendToClient(ws, { type: 'error', message: 'Session not found' });
287
292
  return;
288
293
  }
289
294
 
290
- // Broadcast chat to ALL clients in the room (including sender)
295
+ // Broadcast chat to ALL clients in the session (including sender)
291
296
  room.clients.forEach(client => {
292
297
  if (client.readyState === WebSocket.OPEN) {
293
298
  client.send(JSON.stringify({
294
299
  type: 'chat',
295
300
  text: text,
296
301
  peerId: ws.clientId,
297
- roomId: roomId
302
+ sessionId: sessionId
298
303
  }));
299
304
  }
300
305
  });
@@ -109,14 +109,14 @@ class UniWRTCClient {
109
109
  }
110
110
  }
111
111
 
112
- joinRoom(roomId) {
113
- this.roomId = roomId;
114
- // Durable Objects handle room joining automatically via room parameter
112
+ joinSession(sessionId) {
113
+ this.sessionId = sessionId;
114
+ // Durable Objects handle session joining automatically via room parameter
115
115
  }
116
116
 
117
- leaveRoom() {
118
- if (this.roomId) {
119
- this.roomId = null;
117
+ leaveSession() {
118
+ if (this.sessionId) {
119
+ this.sessionId = null;
120
120
  }
121
121
  }
122
122
 
@@ -188,20 +188,22 @@ class UniWRTCClient {
188
188
  console.log('[UniWRTC] If this helps, consider donating ❤️ → https://coff.ee/draederg');
189
189
  break;
190
190
  case 'joined':
191
- this.roomId = message.roomId;
191
+ this.sessionId = message.sessionId;
192
192
  this.emit('joined', {
193
- roomId: message.roomId,
193
+ sessionId: message.sessionId,
194
194
  clientId: message.clientId,
195
195
  clients: message.clients
196
196
  });
197
197
  break;
198
198
  case 'peer-joined':
199
199
  this.emit('peer-joined', {
200
+ sessionId: message.sessionId,
200
201
  peerId: message.peerId
201
202
  });
202
203
  break;
203
204
  case 'peer-left':
204
205
  this.emit('peer-left', {
206
+ sessionId: message.sessionId,
205
207
  peerId: message.peerId
206
208
  });
207
209
  break;
@@ -237,7 +239,7 @@ class UniWRTCClient {
237
239
  this.emit('chat', {
238
240
  text: message.text,
239
241
  peerId: message.peerId,
240
- roomId: message.roomId
242
+ sessionId: message.sessionId
241
243
  });
242
244
  break;
243
245
  default:
package/src/room.js CHANGED
@@ -17,7 +17,7 @@ export class Room {
17
17
  const clientId = crypto.randomUUID().substring(0, 9);
18
18
  this.clients.set(clientId, server);
19
19
 
20
- console.log(`[Room] Client ${clientId} joined (total: ${this.clients.size})`);
20
+ console.log(`[Room] Client ${clientId} connected (total: ${this.clients.size})`);
21
21
 
22
22
  // Send welcome message
23
23
  server.send(JSON.stringify({
@@ -26,11 +26,7 @@ export class Room {
26
26
  message: 'Connected to UniWRTC signaling room'
27
27
  }));
28
28
 
29
- // Notify existing clients
30
- this.broadcast({
31
- type: 'peer-joined',
32
- clientId: clientId
33
- }, clientId);
29
+ // NOTE: peer-joined is sent when client explicitly joins via 'join' message
34
30
 
35
31
  server.onmessage = async (event) => {
36
32
  try {
@@ -45,10 +41,10 @@ export class Room {
45
41
  server.onclose = () => {
46
42
  console.log(`[Room] Client ${clientId} left`);
47
43
  this.clients.delete(clientId);
44
+ // Note: sessionId should be tracked per client if needed
48
45
  this.broadcast({
49
46
  type: 'peer-left',
50
- peerId: clientId,
51
- clientId: clientId
47
+ peerId: clientId
52
48
  });
53
49
  };
54
50
 
@@ -81,26 +77,32 @@ export class Room {
81
77
  }
82
78
 
83
79
  async handleJoin(clientId, message) {
84
- const { roomId, peerId } = message;
80
+ const { sessionId, peerId } = message;
81
+
82
+ console.log(`[Room] Client ${clientId} joining session ${sessionId}`);
85
83
 
86
84
  // Get list of other peers
87
85
  const peers = Array.from(this.clients.keys())
88
86
  .filter(id => id !== clientId);
89
87
 
88
+ console.log(`[Room] Existing peers in session:`, peers);
89
+
90
90
  const client = this.clients.get(clientId);
91
91
  if (client && client.readyState === WebSocket.OPEN) {
92
92
  // Send joined confirmation (align with server schema)
93
93
  client.send(JSON.stringify({
94
94
  type: 'joined',
95
- roomId: roomId,
95
+ sessionId: sessionId,
96
96
  clientId: clientId,
97
97
  clients: peers
98
98
  }));
99
99
  }
100
100
 
101
101
  // Notify other peers
102
+ console.log(`[Room] Broadcasting peer-joined for ${clientId}`);
102
103
  this.broadcast({
103
104
  type: 'peer-joined',
105
+ sessionId: sessionId,
104
106
  peerId: clientId
105
107
  }, clientId);
106
108
  }