PeerJS – Simple peer-to-peer with WebRTC
peerjs.com
peerjs.com
If you're looking to do "pure" P2P in the browser, we're not there yet as we cannot accept incoming connections without something in between right now.
Maybe you're thinking of the "secure origin" requirement? (The page hosting the JS needs to be a "trusted context", i.e. no file:// and no http://)
You can easily do DataChannel only. For dev work I have a signaling server on a Class C address. Just for testing interop on Safari with my Linux box running signaling and WebRTC agent.
So if u had a web server on that lan, yes. Otherwise u need a mechanism like QR codes or sneaker net a floppy disk with the details to the other peers.
So if you are sharing the same LAN, it does not need internet.
This is because the large IP address space make routing efficient, without the use of NAT.
You do not strictly need a server for signaling in some controlled environment cases (e.g. you can do signaling over sound for closeby peers).
And while it's true that you don't strictly need a server for signalling, most people would expect a library called PeerJS to work P2P over the internet, without requirements to have a speaker/microphone and also without having to be within speaker/microphone range.
If you have a chance take a look at https://webrtcforthecurious.com it is a CC0/Free book I am writing. Would love your opinion and if it helped at all. I also try and write https://github.com/pion/webrtc in a way that others can learn from it. I put all the specific tech in different repos so people can see the big picture.
https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API#...
If all parties were IPv6 first they would still need the secondary services mentioned above, but they could likely broker a direct peer-to-peer connection without a separate service provider.
That being said there is no bypassing of NAT, but you can tunnel through it provided an open connection from within the network. For example HTTP cannot connect to a computer inside a NAT network but it can send a response to a request from inside that network.
Most P2P services make use of a central server to connect users no differently from instant messaging, and thus these services are generally considered a backdoor into a network. BitTorrent is different because it makes use of two protocols doing different things simultaneously.
There are several.
https://en.wikipedia.org/wiki/NAT_traversal
The approaches don't always work, but often are sufficient for consumer grade routers.
> For example HTTP cannot connect to a computer inside a NAT network but it can send a response to a request from inside that network.
Well yeah, that's HTTP. It's a client-server protocol. There is no coordination in connection setup. And it's TCP. It's not designed to do the necessary gymnastics to establish incoming connections through a NAT. So HTTP being HTTP is not an argument for NAT traversal being impossible. a) it's much easier with UDP where you can multiplex incoming and outgoing traffic over a single socket and it'll work for any remote peer as long as your UDP NAT uses EIMs.
(I believe some ISPs may have another level of address translation on their side too...)
The signalling server is different; it proxies metadata between peers like "today, my IP is X" or "I'd like to start a call"
It's still great that they provide this service. I'm curious if anyone else is hosting a slightly more reliable public server as alternative.
you need a STUN server to add in the parts that would include your external ip... that's really all stun does is some service further up the network to give a more reachable address..
I created multi party P2P audio/video chat in ~200 lines of code a while back, here it is: https://github.com/ScottyFillups/p2pchat (see room.js and all the files under client/)
Demo page is here: https://scottyfillups.io/p2pchat
I've had issues with PeerJs in that connections are randomly dropped after a while, and couldn't figure out why.
* Signaling wasn't a big money maker. You are just exchanging small blobs.
* We spent a lot of time helping people debug their networks/explaining WebRTC and making SDKs. I enjoyed the work, but didn't feel like it scaled well.
* Adding features caused major paralysis. Everyone wanted different authentication or different signaling patterns etc...
They all seem really simple, until you actually sit down to do it yourself. Mad props to the FaceTime crew...nobody else has mastered seamless RTC the way they have.
I'm happy to talk to you, too. I do a lot of "let's just talk about real-world things you'll encountering building video features" calls. You don't need to be a Daily (my startup) customer or even plan to be one. I'm kwindla at daily dot co.
I’m curious, did you implement the perfect negotiation logic from the webrtc spec? I’m working on my own WebRTC applications and was hoping that would at least solve the glaring problem in practice
https://www.daily.co/
As you noted below, the signaling itself is the easy part. The long tail of RTCPeerConnection-related corner cases, bandwidth management, analytics and debugging real-world user experience, scaling usage both horizontally and geographically, building features like recording, scaling meeting size beyond 4 participants, optimizing for specific use cases, dealing with browser/platform quirks ... we've tried to make life easy/(ier) for developers in all of those areas.I know well about the mess of difficult to debug technologies that form WebRTC... and on top of that you'll want monitoring, recording, reconnection logic when things go wrong. Of course, add the ability to seamlessly scale when there are lots of users joining a call. The list goes on and on even for a seemingly simple service that "just works"!!
I've been maintaining and improving the oss Kurento server for several years now (https://www.kurento.org/), and the kind of issues that users find is crazy. A slight misconfig in an intermediate proxy can cause random issues very hard to track down.
Shameless plug: We're now building OpenVidu (https://openvidu.io/) on top of Kurento, to provide some of these features. This is a tool that in turn (pun intended) eases writing videoconference services. Most people looking into starting their own WebRTC app from scratch with Kurento, would be better served by OpenVidu!
The ICE/Turn server stuff is also a mess. I ended up installing and hosting a coturn server on digital ocean, and it was a pain. Documentation wasn't great, stackoverflow/forum questions were typically old, and there didn't appear to be any obvious alternatives.
I also tried simple-peer by feross, which seemed to be fine, and most quirks remained as browser issues.
I ended up ditching webrtc and went with a server with websockets. With peer to peer, I'm stuck using a server somewhere, so I'd rather use a websocket server. Webrtc just introduced too many unknown variables. Is there a problem with an ICE/Turn server? Is there a LAN issue? Can browsers vendors properly do p2p to each other without a bunch of "if firefox, do this, if chrome, do this, if something else, panic"? The websocket server took 100% of these concerns out of the equation.
I'd love to be able to use webrtc confidently, but with the current tools for implementing and testing, I don't think I can say it is for myself.
So I think the TLDR is that webrtc peer to peer isn't really consumer-ready. The browser support seems a little hit and miss, testing through a LAN appears to be very flaky, and testing via node/some other framework is spotty at best.
I cut out audio and video from my features, and for the most part, things are working just fine.
Disagree. You can implement functional tests with a loopback signal server. You can implement e2e tests with network emulation (e.g. using iptables/iptraf). Automated testing using the browser WebRTC stack (obviously run basic tests in Node.JS for convenience) is annoying but doable with puppeteer or the like. Just takes time and effort.
The point of WebRTC vs hairpin'ed websocket streams is that the bulk data doesn't pass through intermediate hosts, making the system less costly to run and more privacy preserving. Note that any TURN service required can always be provided or controlled by one of the parties -- it doesn't have to be a centralized service.
And I think if someone is to build this containerized system for testing, it shouldn't necessarily be some app developer like me, it should be someone like the chromium or firefox team that know exactly how the browsers expect to communicate
or via network isolation through networking namespaces (e.g. with podman and lxc)
It is pretty exciting to have such an easy way to have processes in different languages (and different networks!) communicate.
I would really love to find a way to drop the server dependency even https://sean-der.github.io/webrtc-uri/draft-seaduboi-webrtc-... mDNS/Zerconf would be amazing. Even if it just works between WebRTC Agents and not the browser.
There's also the Einstein line: "Everything should be made as simple as possible, but no simpler."
I have no idea if PeerJS is actually too simple, but the "shape" of KaoruAoiShiho's statement seems fine.
Simple would be a real application not subject to the constant churn and complexity of corporate driven web.
WebRTC is a transitional technology and I look forward to the day blocks of IPv6 addresses are granted free to all people at birth and fixed addresses are supported on all devices.
Related question, does anyone know how heavy of a load is a STUN/TURN server? If I build a hobby project using this, and use a (for example) Heroku free tier dyno to host a STUN/TURN nodejs server, how many users/traffic can I expect to be able to run?
But I could not find a solution for an in browser mobile weberc video solution. Pretty much all implementations went through an app.
I also got hung up on trying to use WebRTC with Next.js
Might be time to simplify my stack a little and try again.
You can also have the participant with the beefiest connection act as such a relay, but if every participant is on a metered or upload limited connection, that's not an option.
It's pretty sad actually: We seem to be caught in a perpetual catch-22 of "nobody needs public IP reachability and symmetric bandwidth for home connection, since everyone uses beefy cloud servers anyway" and "we need beefy cloud servers because home connections are asymmetric and NATs are horrible"...
This has some really nice properties. Doing the bandwidth shaping individually for each transport maximizes video quality for each track, but it also means that in an N-way call you have to encode your outgoing video N-1 times. Even with a perfect network connection, you run out of cpu to do the encoding at some point.
Today, on a pretty new-ish laptop the limit for how many outgoing videos you can encode (<waves hands about codecs and settings>) is ~10. On an older Android phone that limit is ~1.
It's possible to imagine changing how WebRTC works so that separate transports can reuse encoded streams. And hopefully that will become possible at some point (https://www.w3.org/TR/webrtc-nv-use-cases/). But not anytime soon. :-(
* https://github.com/peer-calls/peer-calls
* https://github.com/meetecho/janus-gateway
* https://github.com/versatica/mediasoup
(Official GNU software for video calls and more)