I've long been fascinated by distributed hash tables and with the integration of P2P into the browser with WebRTC, I'd love to see an implmentation of some DHT purely in the browser. I'd like to use it as the basis for a distributed data store.
There is an exisiting javascript Kademlia implementation: KadOH. It is for Node.js, but uses a library to transform it to browser-runnable code.
When the library loads you get access to get
and put
functions to access the data store. The issue is that there are two backends currently: UDP and XMPP. I'd like to convert it to use WebRTC.
For DataChannel
s a good place to start is this example with sender and receiver in a single page. (May require installing chromium-beta.)
From KadOH, the class we want to be able to instantiate is KadOH.Node
. The first obvious issue is the first line of the program:
var StateEventEmitter = require('./util/state-eventemitter')
require
is a Node.js convention, however there is a library for browser support. This is used by Jake to build a browser distribution.
Loading that script and executing var node = new KadOH.Node()
results in an error: no bootstrap to join the network
.
A bootstrap is a peer that is already in the network that can be used to find other peers. From looking at the code, it is apparent that KadOH expects bootstrap peers to be passed in a configuration object.
I don't have a static peer running for it to use to bootstrap. Instead, I'm going to try something from ShareIt: PubNub, which is a javascript based publish/subscribe network. You specify listeners and whenever a message is published to your channel all the listeners get called.
A simple script from the docs shows how it works. Opening multiple copies of this page and watching the console shows messages being sent. The question though is what identifying information do we need for peers to communicate to connect to each other over WebRTC?
Based on the serverless WebRTC example there is an offer and an answer. This presents an issue as PubNub can send out the offer, but has no way to route back the answer.
Google's sample application is called AppRTC and it provides a video chat via the Channel API. The DataChannel project uses socketio over Node.js.
For the sake of simplicity, I'm going to try ShareIt's SimpleSignaling server which uses websockets running on Node.js to coordinate peers.
Unfortunately, Heroku doesn't support websockets. The SimpleSignaling serer was apparently designed on dotCloud.
There is a testing server, wss://simplesignaling-piranna.dotcloud.com
, but when I use it the socket never opens. To get the server running on a ec2 instance I did:
sudo apt-get install git nodejs npm
git clone http://github.com/wholcomb/SimpleSignaling
npm install ws
./SimpleSignaling/bin/run_server
For the server I now use ws://ec2-54-242-188-68.compute-1.amazonaws.com:8080
.
For a Synaptian blog article I wrote a wall server. In the process I removed PubNub and use the signaling server for announcing new peers.
Now I've spoken to the creators of KadOH and they recommended PeerJS which uses the PeerServer for signaling. The API seems pretty straightforward. Peer discovery is not handled in PeerJS, so maybe PubNub will come in handy after all.
The first thing I need to figure out is how to add a new transport to KadOH. Existing transports are in lib/network/transport. They are (according to the author):
So, I need to add a webrtc.js and fill it in properly.