gossip-protocol
v1.0.0
Published
Gossip-style message propagation over a WebRTC partial mesh (PartialMesh) with UniWRTC signaling
Maintainers
Readme
gossip-protocol
WebRTC peer-to-peer networking (PartialMesh) plus an example “gossip protocol” implementation that re-propagates messages across connected peers.
This package is intentionally small:
- The library exports
PartialMesh(best-effort WebRTC partial mesh connection manager). - The library also exports
GossipProtocol, a tiny re-propagation helper used by the demo.
Install
npm i gossip-protocolNotes:
- Designed for browsers (WebRTC required). Node.js is used for tooling/tests.
- Signaling uses UniWRTC; by default the demo points at a public server.
Quick start
import { PartialMesh, GossipProtocol } from 'gossip-protocol';
const mesh = new PartialMesh({
sessionId: 'my-room',
minPeers: 1,
maxPeers: 5,
});
const gossip = new GossipProtocol(mesh, { maxHops: 5 });
gossip.on('messageReceived', ({ message, local }) => {
console.log(local ? 'local' : 'remote', message);
});
mesh.on('signaling:connected', ({ clientId }) => {
console.log('signaling connected as', clientId);
});
mesh.on('peer:connected', (peerId) => {
console.log('peer connected', peerId);
});
mesh.on('peer:data', ({ peerId, data }) => {
console.log('from', peerId, data.toString());
});
await mesh.init();
// Later:
// mesh.broadcast('hello');
// mesh.send(peerId, 'direct message');
// mesh.destroy();API
new PartialMesh(config?)
Configuration (all optional):
minPeers(default2): minimum number of peer connections to maintain.maxPeers(default10): maximum number of peer connections to maintain.signalingServer(defaultwss://signal.peer.ooo): UniWRTC signaling server URL.sessionId(defaultdefault-session): room ID used for discovery.autoDiscover(defaulttrue): automatically joinsessionIdon signaling connect.autoConnect(defaulttrue): automatically converge to the target connection count.iceServers(default: Google STUN): passed to WebRTC for ICE.connectionTimeoutMs(default25000): time to wait for a peer to reachconnectbefore retrying.maintenanceIntervalMs(default2000): how often to run the convergence loop.underConnectedResetMs(default0/ disabled): if > 0, triggers a periodichardReset()when the mesh stays belowminPeersdespite having enough discovered peers.
Methods
init(): Promise<void>- Connects to signaling, joins the discovery session (if
autoDiscover), and starts maintenance (ifautoConnect).
- Connects to signaling, joins the discovery session (if
destroy(): void- Tears down peer connections, clears discovered peers, and disconnects signaling.
hardReset(reason?: string): void- Drops all peer connections but keeps signaling/discovery state; useful to recover from rare stuck negotiation/ICE states.
connectToPeer(peerId: string): void- Attempts to establish a WebRTC connection to a discovered peer.
disconnectFromPeer(peerId: string): void- Disconnects from a peer (does not remove it from discovery unless signaling says it left).
send(peerId: string, data: string | Buffer | ArrayBuffer): void- Sends data to a connected peer. Throws if not connected.
broadcast(data: string | Buffer | ArrayBuffer): void- Sends data to all connected peers.
getConnectedPeers(): string[]getDiscoveredPeers(): string[]getPeerCount(): numbergetClientId(): string | nullon(event, handler): void/off(event, handler): void
Events
signaling:connected→{ clientId: string, rawClientId?: string }signaling:disconnectedsignaling:error→anypeer:discovered→peerId: stringpeer:connected→peerId: stringpeer:disconnected→peerId: stringpeer:data→{ peerId: string, data: any }(typically a Buffer-like payload)peer:error→{ peerId: string, error: any }mesh:ready→ emitted whenconnectedPeers.length >= minPeers
Vue 3 demo (gossip)
From the repo root:
npm install
npm run devServes at http://127.0.0.1:5173.
Autostart parameters:
autostart=1maxPeers=20minPeers=3sessionId=your-room
Example:
http://127.0.0.1:5173/?autostart=1&maxPeers=10&minPeers=2&sessionId=my-room
Tests (Playwright e2e loop)
npm test runs a Playwright spec in a loop and prints a per-run summary.
Defaults are defined in scripts/run-e2e-loop.mjs:
- Runs:
5 - Spec:
tests/vue3-15-peers-crossbrowser.spec.ts
Override via env vars:
E2E_RUNSE2E_TIMEOUT_MSE2E_SPECE2E_REPORTERE2E_MAX_RUN_SECONDS
Examples:
E2E_RUNS=10 E2E_TIMEOUT_MS=20000 npm test
E2E_SPEC=tests/vue3-15-peers-crossbrowser.spec.ts npm testOr run the loop script directly:
node scripts/run-e2e-loop.mjs --runs 5 --timeoutMs 15000 --spec tests/vue3-15-peers-crossbrowser.spec.ts --reporter dotNotes / risks
- WebRTC + browser automation is inherently flaky across engines; timeouts are tuned for stability rather than strict guarantees.
- The default signaling endpoint is a third-party service. Treat room IDs and client IDs as metadata visible to that signaling layer.
- This is not a security boundary. If you need authz/authn, abuse protection, persistence, or app-layer encryption, add them in your application.
