Hacker News
Peer-to-peer WebRTC connections with built-in signaling and discovery
mircerlancerous
|next
[-]
bevr1337
|root
|parent
[-]
STUN is only required for NAT traversal. Clients can generate SDP offers without STUN, TURN, and ICE, i.e. offline; but an offer is still useless without some means of signaling.
> Would be great if the browser gave us a way to discover peers fully in-browser
WebRTC never specified signaling so this is a tough challenge. Just my two cents, a first-class SIP API would go a long way towards normalizing signaling.
jckahn
|next
|previous
[-]
LuKks
|root
|parent
|next
[-]
I don't want to force developers to use my opinionated signaling server, but we can provide a best effort and redundant scalable signaling network + peer discovery system by default.
Blind negotiation is important so that the signaling can't even read the SDP/ICE messages, this helps with the goal of letting people run hundreds of signaling servers on their own without need to trust them.
E.g. we need to support signaling using HTTPS to join a tiny Kademlia [decentralized] network of RTCPeerConnection including in the browser. Even a long-running peer with a tab open could be contributing to the network, and a long-running node on a server too because the same code already works everywhere cross-platform.
I will check BitTorrent and Nostr to see if we can expand the signaling options. I'm new into WebRTC and this is an early version, so be patient with me haha :) Thanks
This module is meant to be minimal with no usage assumptions. Imagine a TCP or HTTP server/client API with no opinions, but instead of getting a socket you get a RTCPeerConnection that is connected and ready to use.
You could even run your normal backend over WebRTC + RPC with efficient encoding instead of HTTPS/POST/JSON, because like I said like-webrtc works in Node.js too and it's the same code.
It's not documented in like-webrtc but I will expose the Peer class directly to be more modular e.g.:
const a = new Peer(...) const b = new Peer(...)
a.on('signal', data => b.signal(data)) b.on('signal', data => a.signal(data))
It already works like that internally. If someone wants to benefit from all the features, Noise encryption, perfect negotiation, etc but use different signaling systems then you should be able to do so.
If someone wants to use pure standalone RTCPeerConnection but you want modern WebRTC cross-platform (Node.js, React Native, browser) then you can use: https://github.com/LuKks/webrtc-runtime (used internally by like-webrtc)
If you want to use WebRTC or you have any questions then feel free to contact me:
Here to help
dirkc
|next
|previous
[-]
totetsu
|next
|previous
[-]
LuKks
|root
|parent
[-]
https://speed.cloudflare.com/turn-creds
Free TURN credentials? If it's actually stable and free to use bandwidth e.g. per IP, then we could include it in the iceServers list.
Btw, two peers can have different TURN servers configured and it would still work! WebRTC is amazing.
As for the STUN, it's already included it:
https://github.com/LuKks/like-webrtc/blob/a1a2ac0a90eae7319e...
(In the future, the iceServers might be in a different file location.)
- stun:turn.leet.ar:3478 - stun:stun.l.google.com:19302 - stun:stun.cloudflare.com:3478
I also included my own TURN in like-webrtc because sometimes it helps connecting faster in edge cases with difficult networks but WebRTC can still automatically upgrade to a direct connection transparently after exchanging more ICE candidates or ICE restarts.
LuKks
|next
|previous
[-]
- P2P servers. Listen for peer connections anywhere, even in the browser.
- Direct connections. Connect to peers across devices and networks.
- Built-in signaling. Automatic SDP/ICE exchange and negotiation.
- Identities. Shareable cryptographic addresses instead of IP addresses.
- Peer discovery. Announce and find peers using shared topics.
- WebRTC API. Use data channels, audio/video tracks and transceivers.
- Ready to use. Signaling, STUN and TURN configured by default.
Arya_xiaofan
|root
|parent
[-]
We're working on a related idea with DHttp (https://dhttp.net/), but taking the QUIC/HTTP3 route. Our focus is on making ordinary devices addressable as HTTP endpoints, so existing services can be reached through stable URLs across networks, with access controlled by identity and API path.
It's interesting to see different approaches to making devices more than just clients.
apitman
|next
|previous
[-]
LuKks
|root
|parent
[-]
I don't want to force developers to use my opinionated signaling server, but we can provide a best effort and redundant scalable signaling network + peer discovery system by default.
Blind negotiation is important so that the signaling can't even read the SDP/ICE messages, this helps with the goal of letting people run hundreds of signaling servers on their own without need to trust them.
E.g. we need to support signaling using HTTPS to join a tiny Kademlia [decentralized] network of RTCPeerConnection including in the browser. Even a long-running peer with a tab open could be contributing to the network, and a long-running node on a server too because the same code already works everywhere cross-platform.
I will check BitTorrent and Nostr to see if we can expand the signaling options. I'm new into WebRTC and this is an early version, so be patient with me haha :) Thanks
This module is meant to be minimal with no usage assumptions. Imagine a TCP or HTTP server/client API with no opinions, but instead of getting a socket you get a RTCPeerConnection that is connected and ready to use.
You could even run your normal backend over WebRTC + RPC with efficient encoding instead of HTTPS/POST/JSON, because like I said like-webrtc works in Node.js too and it's the same code.
It's not documented in like-webrtc but I will expose the Peer class directly to be more modular e.g.:
const a = new Peer(...) const b = new Peer(...)
a.on('signal', data => b.signal(data)) b.on('signal', data => a.signal(data))
It already works like that internally. If someone wants to benefit from all the features, Noise encryption, perfect negotiation, etc but use different signaling systems then you should be able to do so.
If someone wants to use pure standalone RTCPeerConnection but you want modern WebRTC cross-platform (Node.js, React Native, browser) then you can use: https://github.com/LuKks/webrtc-runtime (used internally by like-webrtc)
If you want to use WebRTC or you have any questions then feel free to contact me:
Here to help
chr15m
|next
|previous
[-]
wss://party.leet.ar:41337
What happens to anybody who builds on this when you turn off your server in a few months time?
LuKks
|root
|parent
|next
[-]
First, we need E2E encrypted signaling meaning I want the signaling server itself to not be able to read the signals between peers and I'm already working on it. Short-term, a second easy step is to simply run more a few more servers for redundancy.
For context: My main focus for this early version was not decentralized signaling because a simple one works for now, and we can upgrade it afterwards and add redundancy in different countries/jurisdictions. The focus was to build the best intuitive API possible for P2P in the browser and servers with no assumptions e.g. just like a TCP or HTTP server.
In a different comment I explained a better medium-term vision about a decentralized signaling system + decentralized network between long-running browser tabs + node servers.
Also, as someone else pointed out you can still run your own lightweight signaling server (I call it "party" internally, sounds cooler).
I highly appreciate your honest question :)
igbanam
|root
|parent
|previous
[-]
https://github.com/LuKks/like-webrtc/blob/a1a2ac0a90eae7319e...
LuKks
|root
|parent
[-]
I will look into building a HTTPS signaling version so that this can be deployed anywhere easily e.g. CloudFlare workers or your own tiny HTTPS server.
Also, the cool thing about TURN is that two peers with different TURN configured servers are going to still work and connect perfectly, so anyone can use any TURN server and it would still work.
molvqingtai
|next
|previous
[-]
LuKks
|root
|parent
[-]
gavmor
|next
|previous
[-]
It does look kinda neat, though!
LuKks
|root
|parent
|next
[-]
Here "built-in signaling" of course means that you don't worry about it at all, like even when you open new data channels, add new audio/video tracks, etc it's all automatic and perfectly negotiated for you.
If you see the usage example in https://github.com/lukks/like-webrtc there is no sign of any signaling because it's done for you so I think it deserves the "built-in signaling" point :)
I'm working on an update for E2E encrypted SDP/ICE signaling, meaning the server won't be able to read the offers/answers/candidates. After that, to be fair with your reaction and comment, I could clarify in the documentation how the "included signaling" works.
As for peer discovery, it's dependent on the same signaling server but later on it can easily be an actual decentralized network of peers i.e. RTCPeerConnection.
gavmor
|root
|parent
[-]
Edit: it's possible I'm overlooking some aspect of the handshake that's obviated in this case. Perhaps I haven't looked as closely as it deserves.
LuKks
|root
|parent
[-]
The signaling server is acting as a free public service right now, so you're right haha
1. The package connects to an external online WebSocket server. 2. When you do server = rtc.createServer() and server.listen() it tells the external signaling server to record an announcement in a key-value Map which allows permission to receive relayed data from peers that want to connect with you. 3. When a peer does rtc.connect(server.publicKey) they send you via relaying small signaling offers/answers (SDP/ICE) to establish the RTCPeerConnection.
Personally, I just wanted to get the direct peer-to-peer connection perfectly negotiated in the browser as fast as possible.
Signaling can still be improved a lot as per my other replies, and like-webrtc should allow different options for signaling so anyone can do their own thing as well while still benefiting from the cross-platform, intuitive server/client API, the included perfect negotiation, etc.
just_mc
|next
|previous
[-]
LuKks
|root
|parent
[-]
like-webrtc gives you the RTCPeerConnection perfectly negotiated, connected, cross-platform (browsers, Node, React Native), etc but nothing else then you can open a data channel the way you want.
Imagine a TCP or HTTP server/client API, this is the same but you get a peer connection with no extra assumptions and it's up to you what you do next.
WebRTC in servers is also important, e.g. imagine long-running bots or literally just run your backend using WebRTC lol.
- TCP (congested) + HTTPS (insecure centralized global CA) + JSON (slow) versus - UDP (low latency) + RPC (request/response) + binary encoding (fast)
We should start running our centralized backends with WebRTC as a first step to adopt and improve tooling around WebRTC.
That's why I compiled and released a modern WebRTC build version for Node.js:
https://github.com/LuKks/webrtc-runtime (no signaling, no features, etc)
That allows you to use RTCPeerConnection cross-platform anywhere, so I used webrtc-runtime to build like-webrtc (complete solution).