Just to make sure it's clear, this is not a fully in-browser solution; unfortunately an external STUN server is still required. Would be great if the browser gave us a way to discover peers fully in-browser, even just on a local network
> unfortunately an external STUN server is still required.
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.
When developers are passionate about P2P, they don't like seeing a signaling server but that's the standard or specification you could say.
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:
Do I understand correctly that this is normal webRTC with a custom signaling server using private/public key cryptography, and STUN and TURN servers I can use?
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.
Interesting project. I like the idea of letting peers act as servers, even in the browser.
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.
Looks like this depends on a signaling server. I find trystero's approach interesting, where it focuses on using decentralized relays like nostr and BitTorrent for signaling: https://github.com/dmotz/trystero
When developers are passionate about P2P, they don't like seeing a signaling server but that's the standard or specification you could say.
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:
Valid question! While I was building the module I obviously thought about this.
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).
Yes! We should make it easier to deploy your own TURN (relay) and signaling server (I call it "party" internally because it's discovery + signaling = party).
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.
This proves WebRTC works, but you need an API with no assumptions just like a normal TCP or HTTP server/client that allows you to build on top but instead of a socket you would get a RTCPeerConnection ready to use which is what https://github.com/LuKks/like-webrtc gives you for full freedom.
I appreciate it, but when you try to use WebRTC from scratch on your own e.g. connect two RTCPeerConnection instances there is no signaling at all meaning you have to do it and let alone handling SDP negotiation glares
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.
I don't think we have the same definition of "built in"; I would expect it to mean "built into this package/module", not "built into my service which this package acceses".
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.
Actually you're right if we use your [more correct] definition "built into my service which this package acceses"
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.
Its basically the same though. You stop at the relay, then connect to a peer to find other peers. Rther than the relay handing oht p2p, the relay just hands out peer-as-server.
So, sure, we are stiill straining for decentralization.
PeerJS does wrong by forcing opening data channels for you, it's already forcing you into a specific opinion on how it should work. Also, it doesn't work in Node.js. I understand their API idea but it should have been one level lower first, to build on top.
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.
Just to make sure it's clear, this is not a fully in-browser solution; unfortunately an external STUN server is still required. Would be great if the browser gave us a way to discover peers fully in-browser, even just on a local network
> unfortunately an external STUN server is still required.
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.
Great work! Does this offer something beyond what https://trystero.dev/ provides?
When developers are passionate about P2P, they don't like seeing a signaling server but that's the standard or specification you could say.
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:
https://t.me/LucasBarrena
Here to help
My question as well
til: Trystero does Node, Deno, Bun now.
Do I understand correctly that this is normal webRTC with a custom signaling server using private/public key cryptography, and STUN and TURN servers I can use?
That's always what these things are since p2p WebRTC doesn't exist.
Sure, but once a peer is attached, the goal isto match onthe p2p mesh, but the entry is always relau first
Note that this isn't WebRTC's fault. P2P anything doesn't exist anymore.
I just found cloudflare conveniently has some free tier TURN and STUN server allowance.
Did you notice this?
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.
Works across browsers, Node.js, and React Native.
- 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.
Interesting project. I like the idea of letting peers act as servers, even in the browser.
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.
Thank you! Do you have any short code example on how your DHttp works? Is DHttp being built by a company or single developer?
Looks like this depends on a signaling server. I find trystero's approach interesting, where it focuses on using decentralized relays like nostr and BitTorrent for signaling: https://github.com/dmotz/trystero
When developers are passionate about P2P, they don't like seeing a signaling server but that's the standard or specification you could say.
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:
https://t.me/LucasBarrena
Here to help
Repeated here:
https://news.ycombinator.com/item?id=50453906
Single signaling server:
What happens to anybody who builds on this when you turn off your server in a few months time?Valid question! While I was building the module I obviously thought about this.
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 :)
This is the example. When building out yours, you can configure your ports
https://github.com/LuKks/like-webrtc/blob/a1a2ac0a90eae7319e...
Yes! We should make it easier to deploy your own TURN (relay) and signaling server (I call it "party" internally because it's discovery + signaling = party).
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.
There are applications with the same mechanism: https://github.com/molvqingtai/WebChat
This proves WebRTC works, but you need an API with no assumptions just like a normal TCP or HTTP server/client that allows you to build on top but instead of a socket you would get a RTCPeerConnection ready to use which is what https://github.com/LuKks/like-webrtc gives you for full freedom.
It doesn't have built-in signaling and peer discovery, because that's impossible.
It does look kinda neat, though!
I appreciate it, but when you try to use WebRTC from scratch on your own e.g. connect two RTCPeerConnection instances there is no signaling at all meaning you have to do it and let alone handling SDP negotiation glares
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.
I don't think we have the same definition of "built in"; I would expect it to mean "built into this package/module", not "built into my service which this package acceses".
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.
Actually you're right if we use your [more correct] definition "built into my service which this package acceses"
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.
Its basically the same though. You stop at the relay, then connect to a peer to find other peers. Rther than the relay handing oht p2p, the relay just hands out peer-as-server.
So, sure, we are stiill straining for decentralization.
At first glance, it seems extremely similar to PeerJS.
PeerJS does wrong by forcing opening data channels for you, it's already forcing you into a specific opinion on how it should work. Also, it doesn't work in Node.js. I understand their API idea but it should have been one level lower first, to build on top.
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).
[dead]