WebWeWant / webwewant.fyi

If you build websites, you inevitably run into problems. Maybe there’s no way to achieve an aspect of your design using CSS. Or maybe there’s a device feature you really wish you could tap into using JavaScript. Or perhaps the in-browser DevTools don’t give you a key insight you need to do your job. We want to hear about it!
https://webwewant.fyi
MIT License
76 stars 23 forks source link

Local peer discovery, to enable local WebRTC connections #242

Open aarongustafson opened 3 years ago

aarongustafson commented 3 years ago

title: Local peer discovery, to enable local WebRTC connections date: 2020-12-07T22:28:17.424Z submitter: PRIVATE number: 5fceac811b340e1de0f630d3 tags: [ ] discussion: https://github.com/WebWeWant/webwewant.fyi/discussions/ status: [ discussing || in-progress || complete ] related:

This would be an enhancement to the Channel Messaging API.

Browsers could prompt the user to select a remote browser to connect to. Once chosen, the receiving browser would prompt their user to accept the connection. If agreed, a MessageChannel would be established between the two browsers.

The web pages on each end could then communicate over the ports of the channel. If they wished, they could use these ports as a signalling channel to further create WebRTC connections.

The method that the browsers use to establish the MessageChannel can be a simple TCP connection, or perhaps even a PeerConnection itself. The underlying method is not visible to the web application.

Essentially, we're looking for the same flow that Chromecast currently uses. A user tries to cast content. The browser prompts for which device to connect to. Once chosen, a channel is opened and data can be sent/received. The Chromecast is given a web page URL to load, which can then further set up communication if it chooses. In this proposal, when the receiving user accepts the connection, it is expected that the communication would be sent to the target URL, a new tab would be opened if necessary, or they could choose a different registered URL based on the protocol configured by the sending user.

In other words, if both users have a chat application open (let's call it "SuperChat") and User A tries to connect to User B, User A's connection request will contain a protocol identifier (called "chat-proto"), as well as a URL (https://superchat.example.com/). User B will receive the request, and since they already have https://superchat.example.com/ open, an event will be fired on that page, and it will receive the new port. If the page wasn't already open, a new tab with that page will be opened. Alternatively, User B may have configured their own preferred "chat-proto" handler (perhaps, "UltraChat"), and the URL for UltraChat will be used in this same flow instead.

While the local peer discovery is most important to my immediate use case, it also makes sense that the browser could connect to other peers. Perhaps registered users of Google Chrome may want to connect to other folks on their contact list who are online. In effect, the browsers call each other, and then pass the phone off to the other web application to do all the communicating. It doesn't matter how the browsers "call" each other... whether that's a local network, a friend list, or anything else the browser implementers come up with.

This proposal simplifies several use cases for communication. If I want to connect two computers in the same room, I currently have to establish connectivity through a WebRTC signalling server, send some initial information via e-mail or message, connect, and then eventually get connected locally. This is excessive infrastructure, and prone to failure when there is unreliable internet access. Also, it doesn't enable passive peer discovery. For example, suppose I'm on an plane and want to play a game with someone over a shared network, but there is no internet access. If users want to enable themselves to be discoverable, they should be able to do that.

There is no good workaround today for this problem. At best, a browser extension can enable some of this capability, but it isn't a good solution and not exactly cross-platform.

Brad Isbell brad@audiopump.co


If posted, this will appear at https://webwewant.fyi/wants/5fceac811b340e1de0f630d3/

guest271314 commented 3 years ago

One approach is to use clipboard https://gist.github.com/guest271314/04a539c00926e15905b86d05138c113c or a parent HTML page containing <iframe> elements where the signaling is performed through the parent page from the <iframe>s.

bradisbell commented 3 years ago

@guest271314 This proposal is unrelated. I'm referring to the use case where I have several clients on a LAN, and they want to connect their browsers directly to each other. Or, perhaps a use case where the browser is pre-configured to connect to a certain network address somewhere else, transparently from the WebRTC application. In any case, a port that can be opened between browsers on different devices. (I suppose sure, they could be the same device... but that isn't the intent of the proposal.)

guest271314 commented 3 years ago

The same approach applies. WebRTC uses SDP to establish connections. It does not matter if it is the same machine or a different machine. As long as you can orivde signaling, or signaling is completed, by any means, the connection can be establish and data and media can be streamed.

guest271314 commented 3 years ago

@bradisbell See this answer at WebRTC datachannel with manual signaling, example please?

If you and a friend exchange the offer/answer somehow, you now have a direct peer-to-peer connection. This should work around the world (modulo symmetric NATs); no data server involved.

guest271314 commented 3 years ago

One way to do this on the Web would be to use a private or public gist which is served with Access-Control-Allow-Origin: * header to post and read SDP.

I do not fully gather this case

For example, suppose I'm on an plane and want to play a game with someone over a shared network, but there is no internet access.

A similar concept re MessageChannel and Transferable Streams though the connection is intended to be browser (STDIN) <=> native application or shell script (STDOUT), https://bugs.chromium.org/p/chromium/issues/detail?id=1115640.

See Web Capabilities (Project Fugu 🐡).

bradisbell commented 3 years ago

As long as you can orivde signaling, or signaling is completed, by any means, the connection can be establish and data and media can be streamed.

Thanks, I'm aware.

See this answer at WebRTC datachannel with manual signaling, example please?

The issue isn't in doing the signalling, it's having a channel to do it over in the first place. I can't ask users to copy/paste SDP.

One way to do this on the Web would be to use a private or public gist which is served with Access-Control-Allow-Origin: * header to post and read SDP.

Sure, or, I could just use any signalling server at that point. With no internet access, this won't work.

A similar concept re MessageChannel and Transferable Streams though the connection is intended to be browser (STDIN) <=> native application or shell script (STDOUT)

Yes, and using some native application via browser extension is something I've considered to facilitate all this, but it really needs to be built into the browser to be the most useful. Otherwise, everyone has to install an extension, the developers have to maintain it for all platforms, and mobile browsers don't get to participate.

guest271314 commented 3 years ago

Otherwise, everyone has to install an extension, the developers have to maintain it for all platforms, and mobile browsers don't get to participate.

That is essentially how API's are developed.

I do not wait on

needs to be built into the browser

I built it irrespective of what browsers do or do not do.

For example, Web Speech API does not provide any means to capture synthesis output. navigator.mediaDevices.getUserMedia() was evidently intended only for microphone, camera, and when some minutes are read, speech. I have filed numerous bugs, with potential solutions that can be viable, to capture speech synthesis output, for a variety of use cases, for several years now. That has yielded more bans than implementations. This is what a Chromium author linked me to https://bugs.chromium.org/p/chromium/issues/detail?id=1143761#c7 re submitting proposals, that is, FUGU, yet there is no such interface that I could find on the site. I filed an issue https://github.com/GoogleChrome/chromium-dashboard/issues/1112. In the meantime I have written code to capture entire system audio output, and specification application audio output using navigator.mediaDevices.getUserMedia(), outside of each sepecification and implementation https://github.com/guest271314/SpeechSynthesisRecorder/issues/17#issuecomment-749875748. Clearly waiting on other individual or institution to do anything that I can build myself would be futile. I have filed wants here. I was just considering yesterday if I need to review my wants to determine if I have met the requirements myself. If you can use help testing, writing out, and implementing this, you can create the repository and roll your own. Proceed however you see fit. There is an end-to-end encryption example for Instertable Streams, and a Quic version of WebRTC that was based on peer-to-peer communication, I am not sure if that is still active, quic-transport using WebTransport is.

Browsers could prompt the user to select a remote browser to connect to.

How do you intended to do that?

guest271314 commented 3 years ago

You should be able to create a local quick-transport instance https://github.com/guest271314/webtransport that can be connected from an external network.

guest271314 commented 3 years ago

The issue isn't in doing the signalling, it's having a channel to do it over in the first place. I can't ask users to copy/paste SDP.

Let us explore and test our options.

This is the Quic implementation I mentioned earlier