snapdrop icon indicating copy to clipboard operation
snapdrop copied to clipboard

Enable file sharing outside the network by grouping peers by room id and not IP (requested #199)

Open scrodde opened this issue 3 years ago • 19 comments

I have a use case were I want to share photos with my friends on the go without loosing the image quality (Whatsapp, Facebook) and without the hassle of a shared network (both peers are using their own cellular network). This pull request is a POC where files can be shared with remote peers.

Currently the signaling server groups all peers in rooms by their IP-address. All peers in the same room are discoverable to each other. Instead of the server grouping peers based on their IP all peers join a room explicitly using an identifier. The room identifier is a short hashid. This enables peers to join the room on an URL basis. eg snapdrop.net/. A QR-code is displayed for quick mobile device access.

Example URLs

  • https://snapdrop.net/jVED4a2
  • https://snapdrop.net/jM5VYWb

What do you think of this direction?

scrodde avatar Dec 23 '20 13:12 scrodde

Thanks a lot for your work!

(both peers are using their own cellular network).

Can you establish WebRTC connections between peers that are on cellular networks? I've done some experiments when working on #144 and couldn't make it work without a TURN server.

More importantly: The purpose of Snapdrop is to praise simplicity. It's like a religion and I'm a fanatic 😁 This PR makes Snapdrop more complex, because it requires one more step of user interaction. So, for religious reasons I cannot merge this PR in its current form. 😁 I deeply believe we have to keep Snapdrop simple because otherwise we'll burn forever in the hell of complexity [1].

Therefore, in general, I will not add another step to the primary user flow. So, if we want to support this feature, we can add a secondary user flow. There are already sketches in #144. https://sharedrop.io has an implementation, too.

I am not sure about using a QR code though, because most devices don't support user friendly QR code scanning. In #144 we decided for a 6 digit number.

[1] : There is actually a talk by some Google developer telling how their data shows that the probability of an user achieving their goal decays exponentially with the number of required interactions. Thus, Snapdrop's metric: as few steps as possible to share a file in your local network.

RobinLinus avatar Dec 23 '20 20:12 RobinLinus

we could however keep the room system. we could use the geolocation api, send that to the server, let the server calculate easily who is in range, and then just dump in everyone nearby in a room. im not really familiar with WebRTC but hey just an idea.

notangelmario avatar Dec 29 '20 23:12 notangelmario

So basically AirDrop like functionality... P2P Wi-Fi/Bluetooth file transfer (maybe is much easily supported with current bluetooth protocols where they work inconjunct with Wi-Fi without user interaction). It can get ugly fast though. My suggestion is to add such options in setting where we enable experimental/complex features. In my experience these file transfer methods some times do not work and you can never figure out why (which is very frustrating) due to a very simple front end without a view into logs or such. But in any case I would love to be able to "AirDrop" files to Android/Linux/Windows and my refrigerator.

zafzal3 avatar Jan 12 '21 05:01 zafzal3

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

laukeng avatar Nov 23 '21 06:11 laukeng

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

yjmp14 avatar Nov 23 '21 15:11 yjmp14

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

我改动的功能几乎跟你的一样,只不过我的可以输入任意字符。我将用户输入的字符进行URL编码作为房间地址。所以房间名称可以支持任意字符,另外firefox的bug你修复了吗?

laukeng avatar Nov 23 '21 16:11 laukeng

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

你的demo我刚才测试了一下,不输入房间号,同一局域网内的设备互相发现不了。输入房间号后正常。

laukeng avatar Nov 23 '21 17:11 laukeng

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

你的demo我刚才测试了一下,不输入房间号,同一局域网内的设备互相发现不了。输入房间号后正常。

正常是可以的,你确认下其中一个或多个设备是否走代理了,导致IP不一致。

yjmp14 avatar Nov 23 '21 17:11 yjmp14

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

你的demo我刚才测试了一下,不输入房间号,同一局域网内的设备互相发现不了。输入房间号后正常。

正常是可以的,你确认下其中一个或多个设备是否走代理了,导致IP不一致。

没有走代理,手机跟PC同一WIFI下,同一台电脑上开两个浏览器互相也发现不了。输入房间号之后就可以了。

laukeng avatar Nov 23 '21 17:11 laukeng

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

你的demo我刚才测试了一下,不输入房间号,同一局域网内的设备互相发现不了。输入房间号后正常。

正常是可以的,你确认下其中一个或多个设备是否走代理了,导致IP不一致。

而且奇怪的是,不输入房间号的时候,同一台电脑firefox跟safari还有手机上的firefox都互相发现不了。但是我在电脑上firefox中开两个tab,这两个tab之间能发现。

laukeng avatar Nov 23 '21 17:11 laukeng

那就奇怪了,我测试都是 OK 的,确定都没走代理的话 Ctrl+F5 强制刷新看看?

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

你的demo我刚才测试了一下,不输入房间号,同一局域网内的设备互相发现不了。输入房间号后正常。

正常是可以的,你确认下其中一个或多个设备是否走代理了,导致IP不一致。

而且奇怪的是,不输入房间号的时候,同一台电脑firefox跟safari还有手机上的firefox都互相发现不了。但是我在电脑上firefox中开两个tab,这两个tab之间能发现。

Screenshot_2021-11-24-01-16-00-665_com android chrome

我特意下载了 Firefox 进行测试,Windows、Android、iOS 局域网都可以正常发现并成功传文件,不知道你发现不了问题出在哪儿,正常是不应该的,按 Ctrl+F5 强制刷新试试?另外我引入了 #158 的改动,使得各个标签相互独立,互不影响。

yjmp14 avatar Nov 23 '21 17:11 yjmp14

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

你的demo我刚才测试了一下,不输入房间号,同一局域网内的设备互相发现不了。输入房间号后正常。

正常是可以的,你确认下其中一个或多个设备是否走代理了,导致IP不一致。

而且奇怪的是,不输入房间号的时候,同一台电脑firefox跟safari还有手机上的firefox都互相发现不了。但是我在电脑上firefox中开两个tab,这两个tab之间能发现。

看了下服务器日志,知道怎么回事了,你的设备是通过 IPV6 访问的,每个设备的 IPV6 地址不同,导致发现不了,我考虑考虑怎么改进一下。

Temporarily I disabled IPV6 access to my server, you can try again later. Different devices have different public IPV6 addresses, even they are in same LAN, it is a problem, currently the server cant't handle the situation like this. Disable IPV6 access is the only way for now. We may need to submit a new issue.

yjmp14 avatar Nov 23 '21 17:11 yjmp14

If you want this PR to be merged at some time, please stay in English so everyone can understand the ongoing discussions...

fm-sys avatar Nov 23 '21 18:11 fm-sys

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

你的demo我刚才测试了一下,不输入房间号,同一局域网内的设备互相发现不了。输入房间号后正常。

正常是可以的,你确认下其中一个或多个设备是否走代理了,导致IP不一致。

而且奇怪的是,不输入房间号的时候,同一台电脑firefox跟safari还有手机上的firefox都互相发现不了。但是我在电脑上firefox中开两个tab,这两个tab之间能发现。

看了下服务器日志,知道怎么回事了,你的设备是通过 IPV6 访问的,每个设备的 IPV6 地址不同,导致发现不了,我考虑考虑怎么改进一下。

Temporarily I disabled IPV6 access to my server, you can try again later. Different devices have different public IPV6 addresses, even they are in same LAN, it is a problem, currently the server cant't handle the situation like this. Disable IPV6 access is the only way for now. We may need to submit a new issue.

You don't need to disable the server's ipv6. You just need to delete the AAAA record of domain name resolution.

laukeng avatar Nov 24 '21 01:11 laukeng

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

你的demo我刚才测试了一下,不输入房间号,同一局域网内的设备互相发现不了。输入房间号后正常。

正常是可以的,你确认下其中一个或多个设备是否走代理了,导致IP不一致。

而且奇怪的是,不输入房间号的时候,同一台电脑firefox跟safari还有手机上的firefox都互相发现不了。但是我在电脑上firefox中开两个tab,这两个tab之间能发现。

看了下服务器日志,知道怎么回事了,你的设备是通过 IPV6 访问的,每个设备的 IPV6 地址不同,导致发现不了,我考虑考虑怎么改进一下。 Temporarily I disabled IPV6 access to my server, you can try again later. Different devices have different public IPV6 addresses, even they are in same LAN, it is a problem, currently the server cant't handle the situation like this. Disable IPV6 access is the only way for now. We may need to submit a new issue.

You don't need to disable the server's ipv6. You just need to delete the AAAA record of domain name resolution.

Right, that's exactly what I did.

yjmp14 avatar Nov 24 '21 01:11 yjmp14

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

I looked at your source code. The method we use is very similar: you use sessionstorage to store the room ID, and I write the room ID directly into the URL. So, I only need to send a URL such as “https://snapdrop.net/roomid ” to my friend. When he opens the link, he can directly enter the room. After the browser installs the QR code plug-in, the URL can be converted into QR code for sharing. If I find the JS module that generates QR code, I'll add this feature.

laukeng avatar Nov 24 '21 04:11 laukeng

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

I looked at your source code. The method we use is very similar: you use sessionstorage to store the room ID, and I write the room ID directly into the URL. So, I only need to send a URL such as “https://snapdrop.net/roomid ” to my friend. When he opens the link, he can directly enter the room. After the browser installs the QR code plug-in, the URL can be converted into QR code for sharing. If I find the JS module that generates QR code, I'll add this feature.

Just like others disscussed in this thread and #144 , using a share link and QR is more secure, thus you have almost limitless room possibility, but it makes the system complicated. Using a 6-digits room system is much simpler so you don't need a maybe long share link. But 6 digits only have 10^6 possibility, it's less secure. It can't say which choice is better, simplicity and security are conflictive. I personally prefer the 6-digits room system, it's simple enough to use. And there are not so many people using my website, so the security is not my primary concern.

yjmp14 avatar Nov 24 '21 05:11 yjmp14

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

I looked at your source code. The method we use is very similar: you use sessionstorage to store the room ID, and I write the room ID directly into the URL. So, I only need to send a URL such as “https://snapdrop.net/roomid ” to my friend. When he opens the link, he can directly enter the room. After the browser installs the QR code plug-in, the URL can be converted into QR code for sharing. If I find the JS module that generates QR code, I'll add this feature.

Just like others disscussed in this thread and #144 , using a share link and QR is more secure, thus you have almost limitless room possibility, but it makes the system complicated. Using a 6-digits room system is much simpler so you don't need a maybe long share link. But 6 digits only have 10^6 possibility, it's less secure. It can't say which choice is better, simplicity and security are conflictive. I personally prefer the 6-digits room system, it's simple enough to use. And there are not so many people using my website, so the security is not my primary concern.

It doesn't make the system more complex! I made very few changes to the original code. For the feature of room, I only added two lines in the index.js file:

if (/^\/[^\/]+/.test(request.url)) {
    this.ip = decodeURIComponent(request.url.match(/\/([^\/]+)/)[1]);

Of course, I also modified the network. js to make the URL request match my regular expression:

    const nortc = window.isRtcSupported ? '' : '/nortc';
    const url = protocol + '://' + location.host + location.pathname + nortc;

This modification to the network.js file is not necessary. I made this modification to make the server easier to judge whether the client supports webRTC. If the client does not support webRTC, it will not join the room:

if (peer.rtcSupported) {
    this._joinRoom(peer);

laukeng avatar Nov 24 '21 06:11 laukeng

I finished this upgrade. I added a dialog box to enter the room name. Users who enter the same name can find each other. If you enter a blank room name, you return to LAN mode.

Basically I did the same thing, but the UI and logic is more like @RobinLinus discussed in #144 , a 6 digits room system. Please check my fork for codes and my website for live demo. https://www.wulingate.com/en/

I looked at your source code. The method we use is very similar: you use sessionstorage to store the room ID, and I write the room ID directly into the URL. So, I only need to send a URL such as “https://snapdrop.net/roomid ” to my friend. When he opens the link, he can directly enter the room. After the browser installs the QR code plug-in, the URL can be converted into QR code for sharing. If I find the JS module that generates QR code, I'll add this feature.

Just like others disscussed in this thread and #144 , using a share link and QR is more secure, thus you have almost limitless room possibility, but it makes the system complicated. Using a 6-digits room system is much simpler so you don't need a maybe long share link. But 6 digits only have 10^6 possibility, it's less secure. It can't say which choice is better, simplicity and security are conflictive. I personally prefer the 6-digits room system, it's simple enough to use. And there are not so many people using my website, so the security is not my primary concern.

Added QR code support: https://snapdrop.fairysoft.net/

laukeng avatar Nov 25 '21 14:11 laukeng

I would really love to have this implemented as well. This would also solve problems with VPN as #355 #467 #409 and is linked to the following issues: #468

(both peers are using their own cellular network).

Can you establish WebRTC connections between peers that are on cellular networks? I've done some experiments when working on #144 and couldn't make it work without a TURN server.

@RobinLinus I did a little search and apparantly it is possible to exchange signaling information without a TURN server. All we need to do is to do a handshake between the sender and receiver in order to exchange the signaling information.

Info: https://namanjha.in/2022/03/26/webrtc-calls-without-using-stun-turn-or-signaling-server/ Demo: https://namanjha.in/webrtc_demo.html

In the demo user A starts a session and generates and sends the following JSON I to user B:

{"offer":{"sdp":"v=0\r\no=mozilla...THIS_IS_SDPARTA-99.0 7909169004346517863 0 IN IP6 2003:c9:7f20:4b00:1d93:29a3:66d0:8ef1\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 BC:6C:DA:61:41:DB:0A:2B:58:00:89:4B:9E:02:0E:06:2A:DE:16:09:FB:F8:B9:B9:AF:AB:DE:20:3F:96:47:5A\r\na=group:BUNDLE 0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP6 2003:c9:7f20:4b00:1d93:29a3:66d0:8ef1\r\na=sendrecv\r\na=ice-pwd:784d631dddd9657ad83960c16aba3b27\r\na=ice-ufrag:9aa12d62\r\na=mid:0\r\na=setup:actpass\r\na=sctp-port:5000\r\na=max-message-size:1073741823\r\n","type":"offer"},"candidates":[{"candidate":"candidate:0 1 UDP 2122187007 2003:c9:7f20:4b00:1d93:29a3:66d0:8ef1 63279 typ host","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"9aa12d62"},{"candidate":"candidate:1 1 UDP 2122252543 2003:c9:7f20:4b00:1d93:29a3:66d0:8ef1 63280 typ host","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"9aa12d62"},{"candidate":"candidate:2 1 TCP 2105458943 2003:c9:7f20:4b00:1d93:29a3:66d0:8ef1 9 typ host tcptype active","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"9aa12d62"},{"candidate":"candidate:3 1 TCP 2105524479 2003:c9:7f20:4b00:1d93:29a3:66d0:8ef1 9 typ host tcptype active","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"9aa12d62"},{"candidate":"","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"9aa12d62"},null],"info":"goto https://namanjha.in/webrtc_demo.html . Select the answer call option and paste this json into the remote description box"}

User B uses JSON I to generate the following JSON II and sents it back to user A:

{"offer":{"sdp":"v=0\r\no=mozilla...THIS_IS_SDPARTA-99.0 7909169004346517863 0 IN IP6 2003:c9:7f20:4b00:1d93:29a3:66d0:8ef1\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 BC:6C:DA:61:41:DB:0A:2B:58:00:89:4B:9E:02:0E:06:2A:DE:16:09:FB:F8:B9:B9:AF:AB:DE:20:3F:96:47:5A\r\na=group:BUNDLE 0\r\na=ice-options:trickle\r\na=msid-semantic:WMS *\r\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP6 2003:c9:7f20:4b00:1d93:29a3:66d0:8ef1\r\na=sendrecv\r\na=ice-pwd:784d631dddd9657ad83960c16aba3b27\r\na=ice-ufrag:9aa12d62\r\na=mid:0\r\na=setup:actpass\r\na=sctp-port:5000\r\na=max-message-size:1073741823\r\n","type":"offer"},"candidates":[{"candidate":"candidate:0 1 UDP 2122187007 2003:c9:7f20:4b00:1d93:29a3:66d0:8ef1 63279 typ host","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"9aa12d62"},{"candidate":"candidate:1 1 UDP 2122252543 2003:c9:7f20:4b00:1d93:29a3:66d0:8ef1 63280 typ host","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"9aa12d62"},{"candidate":"candidate:2 1 TCP 2105458943 2003:c9:7f20:4b00:1d93:29a3:66d0:8ef1 9 typ host tcptype active","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"9aa12d62"},{"candidate":"candidate:3 1 TCP 2105524479 2003:c9:7f20:4b00:1d93:29a3:66d0:8ef1 9 typ host tcptype active","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"9aa12d62"},{"candidate":"","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"9aa12d62"},null],"info":"goto https://namanjha.in/webrtc_demo.html . Select the answer call option and paste this json into the remote description box"}

User A receives JSON II and inserts it as remote description. Signaling data exchange is complete now -> WebRTC connection is established


This is obviously far too complex UX wise but I could imagine the following:

  1. Users A and B are in the same room and therefore see each other
  2. When user A clicks user B: Session is initiated and JSON I is sent to user B over https
  3. User B receives JSON I and is asked whether it want's to receive File/Message
  4. When user B clicks "yes": JSON II is generated and is sent back to user A over https
  5. Signaling data exchange is complete -> WebRTC connection is established -> File/Message is sent over webRTC

Apart from the room creation it's the same UX as before.

@RobinLinus Do think this would be possible?

schlagmichdoch avatar Jul 27 '22 13:07 schlagmichdoch

(both peers are using their own cellular network).

Can you establish WebRTC connections between peers that are on cellular networks? I've done some experiments when working on #144 and couldn't make it work without a TURN server.

@RobinLinus I did a little search and apparantly it is possible to exchange signaling information without a TURN server. All we need to do is to do a handshake between the sender and receiver in order to exchange the signaling information.

Info: https://namanjha.in/2022/03/26/webrtc-calls-without-using-stun-turn-or-signaling-server/ Demo: https://namanjha.in/webrtc_demo.html

Apparently, this only works when both peers are connected via a IPv6 address which is sadly not the standard everywhere yet: https://www.google.com/intl/en/ipv6/statistics.html#tab=per-country-ipv6-adoption

schlagmichdoch avatar Sep 26 '22 12:09 schlagmichdoch