JSPM

  • Created
  • Published
  • Downloads 11665
  • Score
    100M100P100Q135140F
  • License MIT

Simple, robust, BitTorrent peer wire protocol implementation

Package Exports

  • bittorrent-protocol

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (bittorrent-protocol) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

bittorrent-protocol

Build Status NPM Version NPM Gittip

Simple, robust, BitTorrent wire protocol implementation

browser support

Node.js implementation of the BitTorrent peer wire protocol. The protocol is the main communication layer for BitTorrent file transfer.

Also works in the browser with browserify! This module is used by WebTorrent.

install

npm install bittorrent-protocol

usage

The protocol is implemented as a duplex stream, so all you have to do is pipe to and from it.

duplex streams a.pipe(b).pipe(a)
duplex streams a.pipe(b).pipe(a)

(Images from the "harnessing streams" talk by substack.)

var Protocol = require('bittorrent-protocol')
var net = require('net')

net.createServer(function (socket) {
    var wire = new Protocol()

    // pipe to and from the protocol
    socket.pipe(wire).pipe(socket)

    wire.on('handshake', function (infoHash, peerId) {
        // lets emit a handshake of our own as well
        wire.handshake(new Buffer('my info hash'), new Buffer('my peer id'))
    })

    wire.on('unchoke', function () {
        console.log('peer is no longer choking us: ' + wire.peerChoking)
    })
}).listen(6881)

methods

handshaking

Send and receive a handshake from the peer. This is the first message.

// send a handshake to the peer
wire.handshake(infoHash, peerId, { dht: true })
wire.on('handshake', function (infoHash, peerId, extensions) {
    // receive a handshake
  console.log(extensions.dht) // supports DHT (BEP-0005)
  console.log(extensions.extended) // supports extension protocol (BEP-0010)
})

Both the infoHash and the peerId should be 20 bytes (Buffer or hex-encoded string).

choking

Check if you or the peer is choking.

wire.peerChoking // is the peer choking us?
wire.amChoking // are we choking the peer?

wire.on('choke', function () {
    // the peer is now choking us
})
wire.on('unchoke', function () {
    // peer is no longer choking us
})

interested

See if you or the peer is interested.

wire.peerInterested // is the peer interested in us?
wire.amInterested // are we interested in the peer?

wire.on('interested', function () {
    // peer is now interested
})
wire.on('uninterested', function () {
    // peer is no longer interested
})

bitfield

Exchange piece information with the peer.

// send a bitfield to the peer
wire.bitfield(buffer)
wire.on('bitfield', function (bitfield) {
    // bitfield received from the peer
})

// send a have message indicating that you have a piece
wire.have(pieceIndex)
wire.on('have', function (pieceIndex) {
    // peer has sent you a have message
})

You can always see which pieces the peer has

wire.peerPieces.get(i) // returns true if peer has piece i

wire.peerPieces is a BitField, see docs.

requests

Send and respond to requests for pieces.

// request a block from a peer
wire.request(pieceIndex, offset, length, function (err, block) {
    if (err) {
        // there was an error (peer has started choking us etc)
        return
    }
    // got block
})

// cancel a request to a peer
wire.cancel(pieceIndex, offset, length)

// receive a request from a peer
wire.on('request', function (pieceIndex, offset, length, callback) {
    // ... read block ...
    callback(null, block) // respond back to the peer
})

wire.requests     // list of requests we currently have pending {piece, offset, length}
wire.peerRequests // list of requests the peer currently have pending {piece, offset, length}

You can set a request timeout if you want to.

wire.setTimeout(5000) // head request should take a most 5s to finish

If the timeout is triggered the request callback is called with an error and a timeout event is emitted.

dht and port

You can set the extensions flag dht in the handshake to true if you participate in the torrent dht. Afterwards you can send your dht port.

// send your port to the peer
wire.port(dhtPort)
wire.on('port', function (dhtPort) {
    // peer has sent a port to us
})

You can check to see if the peer supports extensions.

wire.peerExtensions.dht // supports DHT (bep_0005)
wire.peerExtensions.extended // supports extended messages (bep_0005)

keep-alive

You can enable the keep-alive ping (triggered every 60s).

// starts the keep alive
wire.setKeepAlive(true)
wire.on('keep-alive', function () {
    // peer sent a keep alive - just ignore it
})

transfer stats

Check how many bytes you have uploaded and download, and current speed

wire.uploaded // number of bytes uploaded
wire.downloaded // number of bytes downloaded

wire.uploadSpeed() // upload speed - bytes per second
wire.downloadSpeed() // download speed - bytes per second

wire.on('download', function (numberOfBytes) {
    ...
})
wire.on('upload', function (numberOfBytes) {
    ...
})

license

MIT. Copyright (c) Feross Aboukhadijeh.

Includes code from peer-wire-protocol by mafintosh, which is also MIT.