rtc.io-server 1.1.0 → 1.2.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
@@ -21,12 +21,9 @@ server.on("connection", (socket) => {
21
21
  socket.to(roomId).emit("#rtcio:init-offer", { source: socket.id });
22
22
  });
23
23
 
24
- socket.on("disconnecting", () => {
25
- socket.rooms.forEach((roomId) => {
26
- if (roomId === socket.id) return;
27
- socket.to(roomId).emit("user-disconnected", { id: socket.id });
28
- });
29
- });
24
+ // No `disconnecting` handler needed for peer cleanup — the rtc.io-server
25
+ // core emits `#rtcio:peer-left` automatically. Add one only if you have
26
+ // app-level cleanup (presence rosters, room password registries, etc.).
30
27
  });
31
28
 
32
29
  server.listen(3001);
@@ -34,7 +31,12 @@ server.listen(3001);
34
31
 
35
32
  ## What this server does
36
33
 
37
- The rtc.io client multiplexes all WebRTC signaling (offers, answers, ICE candidates, stream metadata) into a single `#rtcio:message` event. This server registers a default handler for that event and relays it to the addressed peer (`socket.to(target).emit(...)`). Everything else — room management, app-level events, presence — is **your** code.
34
+ The rtc.io client multiplexes all WebRTC signaling (offers, answers, ICE candidates, stream metadata) into a single `#rtcio:message` event. This server registers default handlers that:
35
+
36
+ 1. Relay `#rtcio:message` envelopes to the addressed peer (`socket.to(target).emit(...)`).
37
+ 2. Emit a `#rtcio:peer-left` notification to a leaving socket's rooms on `disconnecting`, so existing peers can short-circuit ICE consent-freshness (~30 s) when a tab closes. The client treats this as a hint that's cross-checked against the local WebRTC state; it never tears down a healthy P2P call on the basis of a signaling-only event. See the [signaling protocol](https://docs.rtcio.dev/docs/server/protocol#rtciopeer-left) for the full contract.
38
+
39
+ Everything else — room management, app-level events, presence — is **your** code.
38
40
 
39
41
  ### What you implement
40
42
 
@@ -4,9 +4,29 @@ exports.addDefaultListeners = addDefaultListeners;
4
4
  const events_1 = require("./events");
5
5
  // The rtc.io client multiplexes all signaling (offer/answer/candidate/stream-meta)
6
6
  // over a single MESSAGE channel — these are the only events the server needs to relay.
7
+ //
8
+ // `source` is stamped server-side from the authenticated socket id, never trusted
9
+ // from the client: otherwise a room member could spoof another peer's id and inject
10
+ // offers/answers/candidates that appear to come from someone else. `target` stays
11
+ // client-controlled (it's the routing key) but must be a string.
7
12
  function rtcMessageHandler(socket, data) {
8
- socket.to(data.target).emit(events_1.RtcioEvents.MESSAGE, data);
13
+ if (!data || typeof data.target !== "string")
14
+ return;
15
+ socket.to(data.target).emit(events_1.RtcioEvents.MESSAGE, Object.assign(Object.assign({}, data), { source: socket.id }));
16
+ }
17
+ // Fast-path "this socket is leaving" notification. Without it, peers have to
18
+ // wait on ICE consent freshness (~30 s, RFC 7675) to declare a vanished peer
19
+ // dead. With it, peers can confirm against their own WebRTC layer and tear
20
+ // down the matching RTCPeerConnection in a couple of seconds.
21
+ function rtcDisconnectingHandler(socket) {
22
+ const ownId = socket.id;
23
+ socket.rooms.forEach((roomId) => {
24
+ if (roomId === ownId)
25
+ return;
26
+ socket.to(roomId).emit(events_1.RtcioEvents.PEER_LEFT, { id: ownId });
27
+ });
9
28
  }
10
29
  function addDefaultListeners(socket) {
11
30
  socket.on(events_1.RtcioEvents.MESSAGE, (data) => rtcMessageHandler(socket, data));
31
+ socket.on("disconnecting", () => rtcDisconnectingHandler(socket));
12
32
  }
@@ -1,8 +1,5 @@
1
1
  export declare const RtcioEvents: {
2
- readonly OFFER: "#rtcio:offer";
3
- readonly ANSWER: "#rtcio:answer";
4
- readonly CANDIDATE: "#rtcio:candidate";
5
2
  readonly MESSAGE: "#rtcio:message";
6
- readonly STREAM_META: "#rtcio:stream-meta";
7
3
  readonly INIT_OFFER: "#rtcio:init-offer";
4
+ readonly PEER_LEFT: "#rtcio:peer-left";
8
5
  };
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RtcioEvents = void 0;
4
4
  exports.RtcioEvents = {
5
- OFFER: "#rtcio:offer",
6
- ANSWER: "#rtcio:answer",
7
- CANDIDATE: "#rtcio:candidate",
8
5
  MESSAGE: "#rtcio:message",
9
- STREAM_META: "#rtcio:stream-meta",
10
6
  INIT_OFFER: "#rtcio:init-offer",
7
+ // Server → client. Fan out to a leaving socket's rooms so existing peers
8
+ // can tear down their RTCPeerConnection immediately instead of waiting
9
+ // on ICE consent-freshness (~30 s) to declare the peer dead.
10
+ PEER_LEFT: "#rtcio:peer-left",
11
11
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rtc.io-server",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Signaling server for the rtc.io WebRTC client. Built on socket.io.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -17,22 +17,23 @@
17
17
  "server"
18
18
  ],
19
19
  "license": "MIT",
20
- "author": "",
20
+ "author": "solidet-com",
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "https://github.com/<your-org>/rtc.io.git",
23
+ "url": "git+https://github.com/solidet-com/rtc.io.git",
24
24
  "directory": "rtc.io-server"
25
25
  },
26
26
  "bugs": {
27
- "url": "https://github.com/<your-org>/rtc.io/issues"
27
+ "url": "https://github.com/solidet-com/rtc.io/issues"
28
28
  },
29
- "homepage": "https://github.com/<your-org>/rtc.io#readme",
29
+ "homepage": "https://docs.rtcio.dev",
30
30
  "engines": {
31
31
  "node": ">=18"
32
32
  },
33
33
  "scripts": {
34
34
  "clean": "rm -rf dist",
35
35
  "build": "npm run clean && tsc",
36
+ "typecheck": "tsc --noEmit",
36
37
  "dev": "nodemon --watch '**/*.ts' --exec 'ts-node' ./index.ts",
37
38
  "prepack": "npm run build"
38
39
  },