├── .gitignore ├── LICENSE ├── README.md ├── index.html ├── index.js ├── package.json └── server.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | node_modules 3 | *.ignore 4 | npm-debug.log* 5 | bundle.js 6 | *.swo 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Web-DHT 2 | 3 | Web-DHT is a demo showing one possible way for running a DHT within the web browser. It does this by utilizing [bittorrent-dht](https://github.com/feross/bittorrent-dht) as the DHT protococol and [peer-relay](https://github.com/xuset/peer-relay) as the underlying transport. 4 | 5 | ## How it works 6 | 7 | peer-relay is a p2p message relay that allows for peers to send messages to another without being directly connected to one another. This is possible because peer-relay forms it's own network of peers that it can relay messages through. A dgram-like socket interface is also provided which allows peer-relay to be used by packages that exepct a dgram socket like bittorrent-dht. Check out [peer-relay](https://github.com/xuset/peer-relay) for more info on how it works. 8 | 9 | A short snippet on how things are setup under the hood: 10 | ``` 11 | var PeerRelay = require('peer-relay') 12 | var DHT = require('bittorrent-dht') 13 | 14 | var socket = new PeerRelay.Socket(opts) 15 | 16 | var dht = new DHT({ 17 | socket: socket // All communication will go through the PeerRelay socket 18 | }) 19 | ``` 20 | 21 | ## Setup 22 | 23 | ```bash 24 | git clone https://github.com/xuset/web-dht/ 25 | cd web-dht 26 | npm install 27 | ``` 28 | 29 | To start the bootstrap/first peer run: 30 | ```bash 31 | npm start 8000 32 | ``` 33 | 34 | This will start a NodeJS peer that accepts connections over WebSocket on port 8000. NodeJS peers support incoming WebSockets connections and optionally incoming WebRTC connections while web browser peers only support incoming WebRTC connections. Both support outgoing WebSocket connections. 35 | 36 | To start a web browser peer open the `index.html` file with your browser either by double clicking or starting your own web server. It will attempt to bootstrap itself by first connecting to `ws://localhost:8000`. The `index.html` also provides a basic interface for the DHT by providing the ability to get and put static values in the DHT and also displaying some basic stats for that peer like who the peer is connected to. 37 | 38 | Multiple web browser peers can be started by opening `index.html` in multiple tabs/windows/browsers and they will start to connect to each other. 39 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DHT | PeerRelay 5 | 6 | 7 | 8 | 9 | 49 | 50 | 51 |
52 | 55 |
56 |
57 |
58 |
59 |

Get DHT Value

60 |
61 |
62 |
63 | 64 | 65 | 66 | 67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |

Put DHT Value

75 |
76 |
77 |
78 | 79 | 80 | 81 | 82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |

DHT stats

92 |
93 |
94 |

95 |
96 |
97 |
98 |
99 |
100 |
101 | 102 | 103 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | var PeerRelay = require('peer-relay') 3 | var DHT = require('bittorrent-dht') 4 | var Debug = require('debug') 5 | 6 | Debug.enable('peer-relay:*,bittorrent-dht') 7 | 8 | module.exports.start = function (opts) { 9 | /* The PeerRelay socket relays messages through it's immediately connected peers to allow 10 | * sending messages to peers without needing a direct connection. The socket's interface 11 | * is similar to that of dgram's Socket. The main difference is that hosts are not 12 | * identified by their IP address; instead each peer/host is identified by a randomly 13 | * generated 160-bit hex ID. 14 | */ 15 | var socket = new PeerRelay.Socket(opts) 16 | 17 | var dht = new DHT({ 18 | socket: socket, // All communication will go through the PeerRelay socket 19 | nodeId: socket.peer.id, 20 | bootstrap: false, // The built-in bootstrap method is not compatible with PeerRelay's IDs 21 | isIP: function () { return true } // Prevents DNS resolves on PeerRelay IDs 22 | }) 23 | 24 | dht.listen() 25 | 26 | // Bootstrap manually. Any peer that PeerRelay connects to, add it to the dht 27 | socket.peer.on('peer', function (id) { 28 | dht.addNode({ 29 | host: id.toString('hex'), 30 | port: 0, 31 | id: id 32 | }) 33 | }) 34 | 35 | return dht 36 | } 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "test": "echo \"Error: no test specified\" && exit 1", 5 | "bundle": "standard && browserify index.js -s WebDHT -d -o bundle.js -i ws", 6 | "start": "./server.js", 7 | "prepublish": "npm run -s bundle" 8 | }, 9 | "dependencies": { 10 | "bittorrent-dht": "^7.3.0", 11 | "debug": "^2.2.0", 12 | "peer-relay": "0.0.2" 13 | }, 14 | "devDependencies": { 15 | "browserify": "^13.1.0", 16 | "standard": "^7.1.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var process = require('process') 4 | var WebDHT = require('.') 5 | 6 | var opts = { 7 | port: parseInt(process.argv[2]), 8 | bootstrap: process.argv.slice(3) 9 | } 10 | 11 | if (isNaN(opts.port)) opts.port = 0 12 | 13 | WebDHT.start(opts) 14 | --------------------------------------------------------------------------------