Share
Embed
Peer-to-peer Web
LXJS 2014. http://2014.lxjs.org/
Links mentioned in talk:
- http://talky.io
- https://www.sharefest.me
- http://github.com/mafintosh
- http://webtorrent.io
- https://github.com/feross/simple-peer
- https://github.com/feross/lxjs-chat
Feross Aboukhadijeh
June 28, 2014
Transcript
117 slides
-
How is this possible? •What about security? •What about the
same origin policy? •What about asking the user for permission? •What about users behind firewalls/NATs? •ISN’T THIS CRAZY? -
WebRTC •W3C/IETF web standard •Simple JavaScript API •Supports voice and
video with amazing video quality •Supports arbitrary data (reliable or unreliable) •Peer-to-peer -
“A project to bring realtime communication (RTC) to the open
web platform” ! - Justin Uberti @ Google I/O 2012 -
“I popped in to a recent HTML5 development conference and
was surprised at lack of general knowledge by the “geeks at large” about webrtc." ! - Chris Kranky -
WebTorrent •BitTorrent in the browser (over WebRTC) •Existing BitTorrent clients
•Streaming video playback •Easy to share links •No installation required -
bittorrent bittorrent bittorrent bittorrent webtorrent webtorrent webtorrent.js webtorrent.js webtorrent (webrtc)
bittorrent webtorrent.js IMPORTANT! -
The plan 1. Build a native torrent client (for OS
X, Windows, Linux) 2. Build a web torrent client (for the browser) 3. Add WebRTC to the native client so it can talk to the web clients -
• bittorrent-protocol (wire protocol) • bittorrent-swarm (manage sockets) • bittorrent-dht
(peer discovery) • bittorrent-tracker (client & server, udp & http) • parse-torrent (parse .torrent files) • magnet-uri (parse magnet uris) • ut_metadata (fetch metadata) • bittorrent-client (expose torrents as node.js streams) • webtorrent (stream torrents to VLC) -
Mutual Dependencies • peerflix (used by popcorn time) • torrent-mount
• https://github.com/mafintosh -
<script src=“webtorrent.js”></script> ! <script> var movie = ‘d2474e86c95b19b8bcfdb92bc12c9d44667cfa36’ webtorrent(movie, function
(err, stream) { if (!err) video.src = stream }) </script> -
“I popped in to a recent HTML5 development conference and
was surprised at lack of general knowledge by the “geeks at large” about webrtc." ! - Chris Kranky -
How do peers find each other? •Up to you! •Here’s
an example: •Each user reports to server that they’re online •Make information available to all peers •When a peer wants to connect to another peer, it asks the server for an introduction to that peer -
new RTCPeerConnection(constraints, config) <offer> pc Server createOffer() getUserMedia() addStream() <stream>
“negotiationneeded” setLocalDescription() -
new RTCPeerConnection(constraints, config) <offer> <offer> pc Server createOffer() getUserMedia() addStream()
<stream> “negotiationneeded” setLocalDescription() -
new RTCPeerConnection(constraints, config) <offer> <offer> pc Server new RTCPeerConnection(…) createOffer()
getUserMedia() addStream() <stream> “negotiationneeded” setLocalDescription() -
new RTCPeerConnection(constraints, config) <offer> <offer> pc Server pc new RTCPeerConnection(…)
createOffer() getUserMedia() addStream() <stream> “negotiationneeded” setLocalDescription() -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> pc Server pc new
RTCPeerConnection(…) createOffer() getUserMedia() addStream() <stream> “negotiationneeded” setLocalDescription() -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> pc Server pc new
RTCPeerConnection(…) createOffer() getUserMedia() addStream() <stream> getUserMedia() “negotiationneeded” setLocalDescription() -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> pc Server pc new
RTCPeerConnection(…) createOffer() getUserMedia() addStream() <stream> getUserMedia() <stream> “negotiationneeded” setLocalDescription() -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() pc Server pc
new RTCPeerConnection(…) createOffer() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() pc Server pc
new RTCPeerConnection(…) createOffer() createAnswer() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() pc Server pc
new RTCPeerConnection(…) createOffer() createAnswer() <answer> getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() pc Server pc
new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() pc Server pc
new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() pc Server pc
new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() pc Server pc
new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> pc
Server pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> pc
Server ⋮ pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> pc
Server <candidate> ⋮ pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> pc
Server <candidate> addIceCandidate() ⋮ pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> <candidate>
“icecandidate” pc Server <candidate> addIceCandidate() ⋮ pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> <candidate>
“icecandidate” pc Server <candidate> addIceCandidate() ⋮ ⋮ pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> <candidate>
“icecandidate” pc Server <candidate> addIceCandidate() <candidate> ⋮ ⋮ pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> <candidate>
“icecandidate” pc Server <candidate> addIceCandidate() <candidate> ⋮ ⋮ pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() addIceCandidate() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> <candidate>
“icecandidate” pc Server <candidate> addIceCandidate() <candidate> ⋮ ⋮ pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() addIceCandidate() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” “addstream” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> <candidate>
“icecandidate” pc Server <candidate> addIceCandidate() <candidate> ⋮ ⋮ pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() addIceCandidate() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” “addstream” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> <candidate>
“icecandidate” pc Server <candidate> addIceCandidate() <candidate> ⋮ ⋮ pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() addIceCandidate() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” “addstream” “addstream” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> <candidate>
“icecandidate” pc Server <candidate> addIceCandidate() <candidate> ⋮ ⋮ pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() addIceCandidate() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” “addstream” “addstream” -
setRemoteDescription() new RTCPeerConnection(constraints, config) <offer> <offer> setLocalDescription() “icecandidate” <candidate> <candidate>
“icecandidate” pc Server <candidate> addIceCandidate() <candidate> ⋮ ⋮ pc new RTCPeerConnection(…) createOffer() setLocalDescription() createAnswer() <answer> <answer> setRemoteDescription() addIceCandidate() getUserMedia() addStream() <stream> getUserMedia() addStream() <stream> “negotiationneeded” “addstream” “addstream” -
“signal” new Peer({ initiator: true, stream: s }) new Peer({
stream: s }) <offer> <offer> Peer Server -
“signal” new Peer({ initiator: true, stream: s }) new Peer({
stream: s }) <offer> <offer> Peer Server Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> Peer Server Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> Peer Server Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> Peer Server Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> Peer Server Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() Peer Server Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> Peer Server Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> Peer Server ⋮ Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> Peer Server <candidate> ⋮ Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> Peer Server <candidate> signal() ⋮ Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> <candidate> “signal” Peer Server <candidate> signal() ⋮ Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> <candidate> “signal” Peer Server <candidate> signal() ⋮ ⋮ Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> <candidate> “signal” Peer Server <candidate> signal() <candidate> ⋮ ⋮ Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> <candidate> “signal” Peer Server <candidate> signal() <candidate> signal() ⋮ ⋮ Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> <candidate> “signal” Peer Server <candidate> signal() <candidate> signal() “stream” ⋮ ⋮ Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> <candidate> “signal” Peer Server <candidate> signal() <candidate> signal() “stream” “ready” ⋮ ⋮ Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> <candidate> “signal” Peer Server <candidate> signal() <candidate> signal() “stream” “ready” “stream” ⋮ ⋮ Peer -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> <candidate> “signal” Peer Server <candidate> signal() <candidate> signal() “stream” “ready” “stream” ⋮ ⋮ Peer “ready” -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> <candidate> “signal” Peer Server <candidate> signal() <candidate> signal() “stream” “ready” “stream” ⋮ ⋮ send() <secret message> Peer “ready” -
signal() “signal” new Peer({ initiator: true, stream: s }) new
Peer({ stream: s }) <offer> <offer> “signal” <answer> <answer> signal() “signal” <candidate> <candidate> “signal” Peer Server <candidate> signal() <candidate> signal() “stream” “ready” “stream” ⋮ ⋮ send() “message” <secret message> <secret message> Peer “ready”