├── .gitignore ├── LICENCE ├── README.md ├── browser.js ├── connections ├── relayConnection.js ├── relayStream.js ├── relayStreams.js ├── simpleRelayConnections.js └── simpleRelayNetwork.js ├── example ├── chat │ ├── server.js │ └── static │ │ ├── index.html │ │ └── index.js ├── direct │ ├── server.js │ └── static │ │ ├── index.html │ │ └── index.js ├── discovery.js ├── simple │ ├── server.js │ └── static │ │ ├── index.html │ │ └── index.js └── webrtc │ ├── server.js │ └── static │ ├── index.html │ └── index.js ├── index.js ├── log.js ├── networks ├── connection.js ├── peerNetwork.js ├── relayNetwork.js └── webRTCNetwork.js ├── package.json └── relays ├── answer.js ├── offer.js └── store.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | *.err -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Raynos. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # discovery-network 2 | 3 | A peer to peer discovery network in the cloud 4 | 5 | ## Example 6 | 7 | See [webrtc-stream for more detailed example][1] 8 | 9 | ``` js 10 | var DiscoveryNetwork = require("../../../browser") 11 | , Connection = DiscoveryNetwork.Connection 12 | , RelayStreams = DiscoveryNetwork.RelayStreams 13 | 14 | // Open discovery connection 15 | var conn = Connection("http://localhost:8081/shoe") 16 | 17 | // Identify ourself with a random UUID 18 | conn.identify() 19 | 20 | // Open up a set of relay streams through the connection, on the namespace 21 | RelayStreams(conn, "discovery-network-demo", handleStream) 22 | 23 | // When the relay emits a stream handle it 24 | function handleStream(remotePeerId, stream) { 25 | stream.write("hello!") 26 | 27 | stream.on("data", log) 28 | 29 | function log(data) { 30 | console.log("data from peer", remotePeerId, data) 31 | } 32 | } 33 | ``` 34 | 35 | ## Installation 36 | 37 | `npm install discovery-network` 38 | 39 | ## Contributors 40 | 41 | - Raynos 42 | 43 | ## MIT Licenced 44 | 45 | [1]: https://github.com/Raynos/webrtc-stream/tree/master/example -------------------------------------------------------------------------------- /browser.js: -------------------------------------------------------------------------------- 1 | // God damn 2 | window.Buffer = require("buffer").Buffer 3 | 4 | var Connection = require("./networks/connection") 5 | , PeerNetwork = require("./networks/peerNetwork") 6 | , WebRTCNetwork = require("./networks/webRTCNetwork") 7 | , RelayNetwork = require("./networks/relayNetwork") 8 | , RelayConnection = require("./connections/relayConnection") 9 | , SimpleRelayConnections = require("./connections/simpleRelayConnections") 10 | , RelayStreams = require("./connections/relayStreams") 11 | , RelayStream = require("./connections/relayStream") 12 | , SimpleRelayNetwork = require("./connections/simpleRelayNetwork") 13 | , log = require("./log") 14 | 15 | module.exports = { 16 | Connection: Connection 17 | , PeerNetwork: PeerNetwork 18 | , WebRTCNetwork: WebRTCNetwork 19 | , RelayNetwork: RelayNetwork 20 | , RelayConnection: RelayConnection 21 | , SimpleRelayConnections: SimpleRelayConnections 22 | , RelayStreams: RelayStreams 23 | , RelayStream: RelayStream 24 | , SimpleRelayNetwork: SimpleRelayNetwork 25 | , log: log 26 | } -------------------------------------------------------------------------------- /connections/relayConnection.js: -------------------------------------------------------------------------------- 1 | var EventEmitter = require("events").EventEmitter 2 | , uuid = require("node-uuid") 3 | , log = require("../log") 4 | 5 | module.exports = RelayConnection 6 | 7 | function RelayConnection(connection) { 8 | var mx = connection.mx 9 | , networkName = connection.networkName 10 | , localPeerId = connection.selfId 11 | , relayConnection = new EventEmitter() 12 | , token = uuid() 13 | 14 | relayConnection.receiveAnswer = receiveAnswer 15 | relayConnection.receiveOffer = receiveOffer 16 | relayConnection.createAnswer = createAnswer 17 | relayConnection.createOffer = createOffer 18 | 19 | return relayConnection 20 | 21 | function receiveAnswer(answer) { 22 | log.info("receiveAnswer", answer) 23 | var stream = mx.createStream(networkName + "/relay/answer") 24 | 25 | stream.write(token + answer) 26 | stream.once("data", isOpen) 27 | 28 | function isOpen(data) { 29 | if (data === "open") { 30 | relayConnection.emit("stream", stream) 31 | } 32 | } 33 | } 34 | 35 | function receiveOffer(offer) { 36 | log.info("receiveOffer", offer) 37 | var stream = mx.createStream(networkName + "/relay/offer") 38 | 39 | stream.write(offer + token) 40 | stream.once("data", isOpen) 41 | 42 | function isOpen(data) { 43 | if (data === "open") { 44 | relayConnection.emit("stream", stream) 45 | } 46 | } 47 | } 48 | 49 | function createAnswer(offer) { 50 | return token 51 | } 52 | 53 | function createOffer() { 54 | return token 55 | } 56 | } -------------------------------------------------------------------------------- /connections/relayStream.js: -------------------------------------------------------------------------------- 1 | var SimpleRelayNetwork = require("./simpleRelayNetwork") 2 | , BufferStream = require("buffer-stream") 3 | 4 | module.exports = RelayStream 5 | 6 | function RelayStream(srn, remotePeerId) { 7 | var relayStream = BufferStream().buffer() 8 | 9 | srn.on("stream", handleStream) 10 | 11 | srn.sendOffer(remotePeerId, srn.create(remotePeerId)) 12 | 13 | return relayStream 14 | 15 | function handleStream(peerId, stream) { 16 | if (peerId === remotePeerId) { 17 | relayStream.empty(stream) 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /connections/relayStreams.js: -------------------------------------------------------------------------------- 1 | var SimpleRelayNetwork = require("./simpleRelayNetwork") 2 | , PeerNetwork = require("../networks/peerNetwork") 3 | , EventEmitter = require("events").EventEmitter 4 | , log = require("../log") 5 | 6 | module.exports = RelayStreams 7 | 8 | function RelayStreams(conn, name, callback) { 9 | var srn = SimpleRelayNetwork(conn, name, callback) 10 | , peerNetwork = PeerNetwork(conn, name + "/peer") 11 | , streams = new EventEmitter() 12 | 13 | // when you detect a new peer joining, open a RC to them 14 | peerNetwork.on("peer", handlePeer) 15 | 16 | peerNetwork.join() 17 | 18 | streams.srn = srn 19 | streams.streams = srn.streams 20 | streams.peerNetwork = peerNetwork 21 | streams.destroy = destroy 22 | 23 | return streams 24 | 25 | function handlePeer(remotePeerId) { 26 | log.info("handlePeer", remotePeerId) 27 | srn.sendOffer(remotePeerId, srn.create(remotePeerId)) 28 | } 29 | 30 | function destroy() { 31 | log.info("destroy") 32 | srn.destroy() 33 | peerNetwork.destroy() 34 | 35 | streams.emit("close") 36 | } 37 | } -------------------------------------------------------------------------------- /connections/simpleRelayConnections.js: -------------------------------------------------------------------------------- 1 | var EventEmitter = require("events").EventEmitter 2 | , RelayConnection = require("./relayConnection") 3 | , forEach = require("iterators").forEachSync 4 | , log = require("../log") 5 | 6 | module.exports = SimpleRelayConnections 7 | 8 | function SimpleRelayConnections(conn) { 9 | var relayConnections = {} 10 | , rcs = new EventEmitter() 11 | , streams = rcs.streams = {} 12 | 13 | rcs.create = create 14 | rcs.handleAnswer = handleAnswer 15 | rcs.destroy = destroy 16 | 17 | return rcs 18 | 19 | function create(remotePeerId, offer) { 20 | log.info("create", arguments) 21 | var rc = relayConnections[remotePeerId] = RelayConnection(conn) 22 | if (offer) { 23 | rc.on("stream", handleStream) 24 | 25 | rc.receiveOffer(offer) 26 | 27 | return rc.createAnswer(offer) 28 | } 29 | 30 | return rc.createOffer() 31 | 32 | function handleStream(stream) { 33 | streams[remotePeerId] = stream 34 | 35 | rcs.emit("stream", remotePeerId, stream) 36 | } 37 | } 38 | 39 | function handleAnswer(remotePeerId, answer) { 40 | log.info("handleAnswer", arguments) 41 | var rc = relayConnections[remotePeerId] 42 | 43 | rc.on("stream", handleStream) 44 | 45 | rc.receiveAnswer(answer) 46 | 47 | function handleStream(stream) { 48 | streams[remotePeerId] = stream 49 | 50 | rcs.emit("stream", remotePeerId, stream) 51 | } 52 | } 53 | 54 | function destroy() { 55 | log.info("destroy") 56 | forEach(rcs.streams, close) 57 | 58 | rcs.emit("close") 59 | } 60 | } 61 | 62 | function close(stream) { 63 | stream.end() 64 | stream.destroy() 65 | } -------------------------------------------------------------------------------- /connections/simpleRelayNetwork.js: -------------------------------------------------------------------------------- 1 | var SimpleRelayConnections = require("./simpleRelayConnections") 2 | , RelayNetwork = require("../networks/relayNetwork") 3 | , EventEmitter = require("events").EventEmitter 4 | , log = require("../log") 5 | 6 | module.exports = SimpleRelayNetwork 7 | 8 | function SimpleRelayNetwork(conn, name, callback) { 9 | var rcs = SimpleRelayConnections(conn) 10 | , relayNetwork = RelayNetwork(conn, name + "/relay") 11 | , network = new EventEmitter() 12 | 13 | // when we detect an offer from the relay network, open an RC to them 14 | relayNetwork.on("offer", handleOffer) 15 | 16 | // incoming answers from another peer 17 | relayNetwork.on("answer", rcs.handleAnswer) 18 | 19 | // handle streams coming out of rcs 20 | rcs.on("stream", reemit) 21 | 22 | if (callback) { 23 | rcs.on("stream", callback) 24 | } 25 | 26 | network.rcs = rcs 27 | network.create = rcs.create 28 | network.sendOffer = relayNetwork.sendOffer 29 | network.streams = rcs.streams 30 | network.relayNetwork = relayNetwork 31 | network.destroy = destroy 32 | 33 | return network 34 | 35 | function handleOffer(remotePeerId, offer) { 36 | log.info("handleOffer", remotePeerId, offer) 37 | var answer = rcs.create(remotePeerId, offer) 38 | 39 | relayNetwork.sendAnswer(remotePeerId, answer) 40 | } 41 | 42 | function reemit(peerId, stream) { 43 | network.emit("stream", peerId, stream) 44 | } 45 | 46 | function destroy() { 47 | log.info("destroy") 48 | rcs.destroy() 49 | relayNetwork.destroy() 50 | 51 | network.emit("close") 52 | } 53 | } -------------------------------------------------------------------------------- /example/chat/server.js: -------------------------------------------------------------------------------- 1 | var browserifyServer = require("browserify-server") 2 | 3 | var server = browserifyServer.listen(__dirname, 8080) 4 | 5 | console.log("running on port 8080") -------------------------------------------------------------------------------- /example/chat/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | chat demo 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example/chat/static/index.js: -------------------------------------------------------------------------------- 1 | var DiscoveryNetwork = require("../../../browser") 2 | , discoveryLog = DiscoveryNetwork.log 3 | , Connection = DiscoveryNetwork.Connection 4 | , PeerNetwork = DiscoveryNetwork.PeerNetwork 5 | , RelayNetwork = DiscoveryNetwork.RelayNetwork 6 | , SimpleRelayConnections = DiscoveryNetwork.SimpleRelayConnections 7 | , forEach = require("iterators").forEachSync 8 | 9 | var chatBox = document.getElementById("chat-box") 10 | , chatMessages = document.getElementById("chat-messages") 11 | , chatButton = document.getElementById("chat-button") 12 | // Open discovery connection 13 | , conn = Connection("http://localhost:8081/shoe") 14 | , rcs = SimpleRelayConnections(conn) 15 | 16 | chatButton.addEventListener("click", sendMessage) 17 | 18 | chatButton.disabled = true 19 | 20 | // Enable logging 21 | discoveryLog.enabled = true 22 | 23 | // Identify ourself with a random UUID 24 | conn.identify() 25 | 26 | var peerNetwork = PeerNetwork(conn, "discovery-network-demo:peer") 27 | , relayNetwork = RelayNetwork(conn, "discovery-network-demo:relay") 28 | 29 | // when you detect a new peer joining, open a RC to them 30 | peerNetwork.on("peer", handlePeer) 31 | 32 | // when we detect an offer from the relay network, open an RC to them 33 | relayNetwork.on("offer", handleOffer) 34 | 35 | // incoming answers from another peer 36 | relayNetwork.on("answer", rcs.handleAnswer) 37 | 38 | // handle streams coming out of rcs 39 | rcs.on("stream", handleStream) 40 | 41 | peerNetwork.join() 42 | 43 | function handlePeer(remotePeerId) { 44 | var offer = rcs.create(remotePeerId) 45 | 46 | relayNetwork.sendOffer(remotePeerId, offer) 47 | } 48 | 49 | function handleOffer(remotePeerId, offer) { 50 | var answer = rcs.create(remotePeerId, offer) 51 | 52 | relayNetwork.sendAnswer(remotePeerId, answer) 53 | } 54 | 55 | function handleStream(remotePeerId, stream) { 56 | chatButton.disabled = false 57 | 58 | stream.on("data", renderMessage) 59 | 60 | function renderMessage(data) { 61 | var msg = document.createElement("div") 62 | msg.textContent = "stranger[" + remotePeerId + "]: " + data 63 | chatMessages.appendChild(msg) 64 | } 65 | } 66 | 67 | function sendMessage() { 68 | var text = chatBox.value 69 | chatBox.value = "" 70 | forEach(rcs.streams, send) 71 | 72 | var msg = document.createElement("div") 73 | msg.textContent = "self: " + text 74 | chatMessages.appendChild(msg) 75 | 76 | function send(stream) { 77 | stream.write(text) 78 | } 79 | } -------------------------------------------------------------------------------- /example/direct/server.js: -------------------------------------------------------------------------------- 1 | var browserifyServer = require("browserify-server") 2 | 3 | var server = browserifyServer.listen(__dirname, 8080) 4 | 5 | console.log("running on port 8080") -------------------------------------------------------------------------------- /example/direct/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | direct demo 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example/direct/static/index.js: -------------------------------------------------------------------------------- 1 | var DiscoveryNetwork = require("../../../browser") 2 | , Connection = DiscoveryNetwork.Connection 3 | , RelayStream = DiscoveryNetwork.RelayStream 4 | , SimpleRelayNetwork = DiscoveryNetwork.SimpleRelayNetwork 5 | , PeerNetwork = DiscoveryNetwork.PeerNetwork 6 | 7 | DiscoveryNetwork.log.enabled = true 8 | 9 | // Open discovery connection 10 | var conn = Connection("http://localhost:8081/shoe") 11 | , srn = SimpleRelayNetwork(conn, "discovery-network-demo", handleStream) 12 | , peerNetwork = PeerNetwork(conn) 13 | , opened = { 14 | 15 | } 16 | 17 | peerNetwork.on("peer", function (peerId) { 18 | // Open up a set of relay streams through the connection, on the namespace 19 | var stream = RelayStream(srn, peerId) 20 | opened[peerId] = true 21 | 22 | stream.on("data", log) 23 | 24 | stream.write("goodbye!") 25 | 26 | function log(data) { 27 | console.log("[PEER1]", peerId, data) 28 | } 29 | }) 30 | 31 | peerNetwork.join() 32 | 33 | // When the relay emits a stream handle it 34 | function handleStream(remotePeerId, stream) { 35 | if (opened[remotePeerId] !== true) { 36 | stream.write("hello!") 37 | 38 | stream.on("data", log) 39 | } 40 | 41 | function log(data) { 42 | console.log("[PEER2]", remotePeerId, data) 43 | } 44 | } -------------------------------------------------------------------------------- /example/discovery.js: -------------------------------------------------------------------------------- 1 | var http = require("http") 2 | , shoe = require("mux-demux-shoe") 3 | , DiscoveryNetwork = require("..") 4 | 5 | var server = http.createServer().listen(8081) 6 | , network = DiscoveryNetwork({ 7 | log: true 8 | }) 9 | 10 | shoe(network).install(server, "/shoe") 11 | 12 | console.log("running on port 8081") -------------------------------------------------------------------------------- /example/simple/server.js: -------------------------------------------------------------------------------- 1 | var browserifyServer = require("browserify-server") 2 | 3 | var server = browserifyServer.listen(__dirname, 8080) 4 | 5 | console.log("running on port 8080") -------------------------------------------------------------------------------- /example/simple/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | simple demo 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example/simple/static/index.js: -------------------------------------------------------------------------------- 1 | var DiscoveryNetwork = require("../../../browser") 2 | , Connection = DiscoveryNetwork.Connection 3 | , RelayStreams = DiscoveryNetwork.RelayStreams 4 | 5 | DiscoveryNetwork.log.enabled = true 6 | 7 | // Open discovery connection 8 | var conn = Connection("http://localhost:8081/shoe") 9 | 10 | // Open up a set of relay streams through the connection, on the namespace 11 | RelayStreams(conn, "discovery-network-demo", handleStream) 12 | 13 | // When the relay emits a stream handle it 14 | function handleStream(remotePeerId, stream) { 15 | stream.write("hello!") 16 | 17 | stream.on("data", log) 18 | 19 | function log(data) { 20 | console.log("data from peer", remotePeerId, data) 21 | } 22 | } -------------------------------------------------------------------------------- /example/webrtc/server.js: -------------------------------------------------------------------------------- 1 | var browserifyServer = require("browserify-server") 2 | 3 | var server = browserifyServer.listen(__dirname, 8080) 4 | 5 | console.log("running on port 8080") -------------------------------------------------------------------------------- /example/webrtc/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | WebRTC demo 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /example/webrtc/static/index.js: -------------------------------------------------------------------------------- 1 | var WebRTC = require("webrtc-stream") 2 | , MediaStream = WebRTC.MediaStream 3 | , WebRTCStreams = WebRTC.WebRTCStreams 4 | , DiscoveryNetwork = require("../../../browser") 5 | , Connection = DiscoveryNetwork.Connection 6 | 7 | var localVideo = document.getElementById("local-webrtc") 8 | , remoteVideos = document.getElementById("remote-videos") 9 | 10 | WebRTC.log.enabled = true 11 | DiscoveryNetwork.log.enabled = true 12 | 13 | MediaStream.local(localVideo, function (myMediaStream) { 14 | var conn = Connection("http://localhost:8081/shoe") 15 | 16 | WebRTCStreams(conn, "mediaStreams-demo", myMediaStream, renderStream) 17 | 18 | function renderStream(remotePeerId, stream) { 19 | var remoteVideo = document.createElement("video") 20 | remoteVideo.autoplay = true 21 | remoteVideos.appendChild(remoteVideo) 22 | MediaStream.remote(remoteVideo, stream) 23 | } 24 | }) -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var StreamRouter = require("stream-router") 2 | , EchoChamber = require("multi-channel-mdm") 3 | , logger = require("mux-demux-logger") 4 | , handleOffer = require("./relays/offer") 5 | , handleAnswer = require("./relays/answer") 6 | 7 | module.exports = DiscoveryNetwork 8 | 9 | function DiscoveryNetwork(options) { 10 | if (typeof options === "string" || !options) { 11 | options = { 12 | prefix: options || null 13 | } 14 | } 15 | 16 | var log = options.log 17 | , prefix = options.prefix || "/discovery" 18 | , router = StreamRouter() 19 | 20 | router.addRoute(prefix + "/peer/echo/:streamName", EchoChamber()) 21 | router.addRoute(prefix + "/webrtc/echo/:streamName", EchoChamber()) 22 | router.addRoute(prefix + "/relay/echo/:streamName", EchoChamber()) 23 | router.addRoute(prefix + "/relay/offer", handleOffer) 24 | router.addRoute(prefix + "/relay/answer", handleAnswer) 25 | 26 | if (log) { 27 | return logger(router) 28 | } 29 | return router 30 | } -------------------------------------------------------------------------------- /log.js: -------------------------------------------------------------------------------- 1 | module.exports = require("browser-log").create() -------------------------------------------------------------------------------- /networks/connection.js: -------------------------------------------------------------------------------- 1 | var shoe = require("shoe") 2 | , MuxDemux = require("mux-demux") 3 | , EventEmitter = require("events").EventEmitter 4 | , uuid = require("node-uuid") 5 | 6 | module.exports = Connection 7 | 8 | function Connection(uri, networkName) { 9 | networkName = networkName || "/discovery" 10 | 11 | var stream = shoe(uri || "/shoe") 12 | , mx = MuxDemux() 13 | , conn = new EventEmitter() 14 | 15 | stream.pipe(mx).pipe(stream) 16 | 17 | conn.selfId = uuid() 18 | conn.networkName = networkName 19 | conn.identify = identify 20 | conn.mx = mx 21 | conn.stream = stream 22 | 23 | stream.once("end", conn.emit.bind(conn, "end")) 24 | stream.once("connect", conn.emit.bind(conn, "connect")) 25 | 26 | return conn 27 | 28 | function identify(user) { 29 | conn.selfId = user.toString() 30 | } 31 | } -------------------------------------------------------------------------------- /networks/peerNetwork.js: -------------------------------------------------------------------------------- 1 | var RemoteEventEmitter = require("remote-events") 2 | , EventEmitter = require("events").EventEmitter 3 | , log = require("../log") 4 | 5 | module.exports = PeerNetwork 6 | 7 | function PeerNetwork(connection, channel) { 8 | var mx = connection.mx 9 | , networkName = connection.networkName 10 | , localPeerId = connection.selfId 11 | , peerStream = mx.createStream(networkName + "/peer/echo/" + 12 | encodeURIComponent(channel)) 13 | , peerEmitter = new RemoteEventEmitter() 14 | , network = new EventEmitter() 15 | 16 | peerStream.pipe(peerEmitter.getStream()).pipe(peerStream) 17 | 18 | peerEmitter.on("peer", onpeer) 19 | 20 | network.join = join 21 | network.destroy = destroy 22 | 23 | return network 24 | 25 | function onpeer(remotePeerId) { 26 | log.info("onpeer", remotePeerId) 27 | if (remotePeerId !== localPeerId) { 28 | network.emit("peer", remotePeerId) 29 | } 30 | } 31 | 32 | function join(user) { 33 | log.info("join", user) 34 | if (user) { 35 | localPeerId = user.toString() 36 | } 37 | peerEmitter.emit("peer", localPeerId) 38 | } 39 | 40 | function destroy() { 41 | peerStream.end() 42 | peerStream.destroy() 43 | 44 | network.emit("close") 45 | } 46 | } -------------------------------------------------------------------------------- /networks/relayNetwork.js: -------------------------------------------------------------------------------- 1 | var RemoteEventEmitter = require("remote-events") 2 | , EventEmitter = require("events").EventEmitter 3 | , log = require("../log") 4 | 5 | module.exports = RelayNetwork 6 | 7 | function RelayNetwork(connection, channel) { 8 | var mx = connection.mx 9 | , networkName = connection.networkName 10 | , localPeerId = connection.selfId 11 | , relayStream = mx.createStream(networkName + "/relay/echo/" + 12 | encodeURIComponent(channel)) 13 | , relayEmitter = new RemoteEventEmitter() 14 | , network = new EventEmitter() 15 | 16 | relayStream.pipe(relayEmitter.getStream()).pipe(relayStream) 17 | 18 | relayEmitter.on("offer", onoffer) 19 | relayEmitter.on("answer", onanswer) 20 | 21 | network.sendAnswer = sendAnswer 22 | network.sendOffer = sendOffer 23 | 24 | network.identify = identify 25 | network.destroy = destroy 26 | 27 | return network 28 | 29 | function onoffer(toPeerId, fromPeerId, offer) { 30 | log.verbose("onoffer", arguments) 31 | if (toPeerId === localPeerId) { 32 | network.emit("offer", fromPeerId, offer) 33 | } 34 | } 35 | 36 | function onanswer(toPeerId, fromPeerId, answer) { 37 | log.verbose("onanswer", arguments) 38 | if (toPeerId === localPeerId) { 39 | network.emit("answer", fromPeerId, answer) 40 | } 41 | } 42 | 43 | function sendOffer(remotePeerId, offer) { 44 | log.info("sendOffer", arguments) 45 | relayEmitter.emit("offer", remotePeerId, localPeerId, offer) 46 | } 47 | 48 | function sendAnswer(remotePeerId, answer) { 49 | log.info("sendAnswer", arguments) 50 | relayEmitter.emit("answer", remotePeerId, localPeerId, answer) 51 | } 52 | 53 | function identify(user) { 54 | localPeerId = user.toString() 55 | } 56 | 57 | function destroy() { 58 | relayStream.end() 59 | relayStream.destroy() 60 | 61 | network.emit("close") 62 | } 63 | } -------------------------------------------------------------------------------- /networks/webRTCNetwork.js: -------------------------------------------------------------------------------- 1 | var RemoteEventEmitter = require("remote-events") 2 | , EventEmitter = require("events").EventEmitter 3 | , log = require("../log") 4 | , SessionDescription = window.SessionDescription 5 | , IceCandidate = window.IceCandidate 6 | 7 | module.exports = WebRTCNetwork 8 | 9 | function WebRTCNetwork(connection, channel) { 10 | var mx = connection.mx 11 | , networkName = connection.networkName 12 | , localPeerId = connection.selfId 13 | , webrtcStream = mx.createStream(networkName + "/webrtc/echo/" + 14 | encodeURIComponent(channel)) 15 | , webrtcEmitter = new RemoteEventEmitter() 16 | , network = new EventEmitter() 17 | 18 | webrtcStream.pipe(webrtcEmitter.getStream()).pipe(webrtcStream) 19 | 20 | webrtcEmitter.on("offer", onoffer) 21 | webrtcEmitter.on("answer", onanswer) 22 | webrtcEmitter.on("candidate", oncandidate) 23 | 24 | network.sendOffer = sendOffer 25 | network.sendAnswer = sendAnswer 26 | network.sendCandidate = sendCandidate 27 | 28 | network.identify = identify 29 | network.destroy = destroy 30 | 31 | return network 32 | 33 | function onoffer(toPeerId, fromPeerId, offer) { 34 | log.verbose("onoffer", arguments) 35 | if (toPeerId === localPeerId) { 36 | network.emit("offer", fromPeerId, new SessionDescription(offer)) 37 | } 38 | } 39 | 40 | function onanswer(toPeerId, fromPeerId, answer) { 41 | log.verbose("onanswer", arguments) 42 | if (toPeerId === localPeerId) { 43 | network.emit("answer", fromPeerId, new SessionDescription(answer)) 44 | } 45 | } 46 | 47 | function oncandidate(toPeerId, fromPeerId, candidate) { 48 | log.silly("oncandidate", arguments) 49 | if (toPeerId === localPeerId) { 50 | network.emit("candidate", fromPeerId 51 | , new IceCandidate(candidate.label, candidate.candidate)) 52 | } 53 | } 54 | 55 | function sendOffer(remotePeerId, offer) { 56 | log.info("sendOffer", arguments) 57 | // sending an offer 58 | webrtcEmitter.emit("offer", remotePeerId, localPeerId, offer.toSdp()) 59 | } 60 | 61 | function sendAnswer(remotePeerId, answer) { 62 | log.info("sendAnswer", arguments) 63 | 64 | webrtcEmitter.emit("answer", remotePeerId, localPeerId, answer.toSdp()) 65 | } 66 | 67 | function sendCandidate(remotePeerId, candidate) { 68 | log.silly("candidate", arguments) 69 | webrtcEmitter.emit("candidate", remotePeerId, localPeerId, { 70 | label: candidate.label 71 | , candidate: candidate.toSdp() 72 | }) 73 | } 74 | 75 | function identify(user) { 76 | localPeerId = user.toString() 77 | } 78 | 79 | function destroy() { 80 | webrtcStream.end() 81 | webrtcStream.destroy() 82 | 83 | network.emit("close") 84 | } 85 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "discovery-network", 3 | "version": "0.6.1", 4 | "description": "A peer to peer discovery network in the cloud", 5 | "keywords": [], 6 | "author": "Raynos ", 7 | "repository": "git://github.com/Raynos/discovery-network.git", 8 | "main": "index", 9 | "homepage": "https://github.com/Raynos/discovery-network", 10 | "contributors": [ 11 | { 12 | "name": "Jake Verbaten" 13 | } 14 | ], 15 | "browserify": "browser.js", 16 | "bugs": { 17 | "url": "https://github.com/Raynos/discovery-network/issues", 18 | "email": "raynos2@gmail.com" 19 | }, 20 | "dependencies": { 21 | "mux-demux": "~3.2.0", 22 | "stream-router": "~0.1.0", 23 | "multi-channel-mdm": "~0.5.1", 24 | "mux-demux-logger": "0.1.0", 25 | "shoe": "0.0.4", 26 | "node-uuid": "~1.3.3", 27 | "remote-events": "~1.1.1", 28 | "browser-log": "0.0.2", 29 | "stream-store": "~0.2.0", 30 | "iterators": "~0.2.0", 31 | "buffer-stream": "0.0.1" 32 | }, 33 | "devDependencies": { 34 | "browserify-server": "~0.3.1", 35 | "mux-demux-shoe": "~0.2.7", 36 | "iterators": "~0.2.0", 37 | "webrtc-stream": "~0.5.0" 38 | }, 39 | "licenses": [ 40 | { 41 | "type": "MIT", 42 | "url": "http://github.com/Raynos/discovery-network/raw/master/LICENSE" 43 | } 44 | ], 45 | "scripts": {} 46 | } 47 | -------------------------------------------------------------------------------- /relays/answer.js: -------------------------------------------------------------------------------- 1 | var store = require("./store") 2 | 3 | module.exports = handleAnswer 4 | 5 | function handleAnswer(answerStream) { 6 | answerStream.once("data", ondata) 7 | 8 | function ondata(token) { 9 | var offerStream = store.get(token) 10 | 11 | if (offerStream === null) { 12 | return answerStream.error("invalid answer token") 13 | } 14 | 15 | store.delete(token) 16 | 17 | offerStream.write("open") 18 | answerStream.write("open") 19 | answerStream.pipe(offerStream).pipe(answerStream) 20 | } 21 | } -------------------------------------------------------------------------------- /relays/offer.js: -------------------------------------------------------------------------------- 1 | var store = require("./store") 2 | 3 | module.exports = handleOffer 4 | 5 | function handleOffer(offerStream) { 6 | offerStream.once("data", ondata) 7 | 8 | function ondata(token) { 9 | store.set(token, offerStream) 10 | } 11 | } -------------------------------------------------------------------------------- /relays/store.js: -------------------------------------------------------------------------------- 1 | var StreamStore = require("stream-store") 2 | , store = StreamStore(function () { 3 | return null 4 | }) 5 | 6 | module.exports = store --------------------------------------------------------------------------------