Grenache Node.js HTTP

1.0.1 · active · verified Wed Apr 22

Grenache Node.js HTTP implementation, currently at stable version 1.0.1, is a specialized micro-framework designed for building performant microservices in Node.js environments. It stands out by utilizing Distributed Hash Tables (DHT), similar to those found in Bittorrent, to facilitate peer-to-peer connections rather than traditional centralized brokers. This package provides the HTTP transport layer for Grenache, enabling the creation of RPC servers and clients that announce and discover services over an overlay network managed by external 'Grape' DHT nodes. Its release cadence follows the broader Grenache ecosystem. Key differentiators include its decentralized service discovery, direct peer-to-peer communication, and focus on optimized performance, moving beyond conventional request-response patterns by leveraging a robust, distributed network infrastructure. It specifically abstracts away the complexities of DHT interaction for HTTP-based service communication.

Common errors

Warnings

Install

Imports

Quickstart

This example demonstrates how to set up two Grenache Grape DHT instances, create a Grenache RPC server that announces a service, and an RPC client that requests data from it over HTTP.

/*
  Before running this code, you need to install grenache-grape globally:
  npm i -g grenache-grape

  Then, start two Grape instances:
  grape --dp 20001 --aph 30001 --bn '127.0.0.1:20002'
  grape --dp 20002 --aph 40001 --bn '127.0.0.1:20001'
*/

const Link = require('grenache-nodejs-link')
const { PeerRPCServer, PeerRPCClient } = require('grenache-nodejs-http')

// RPC Server
const serverLink = new Link({
  grape: 'http://127.0.0.1:30001'
})
serverLink.start()

const peerServer = new PeerRPCServer(serverLink, {
  timeout: 300000
})
peerServer.init()

const service = peerServer.transport('server')
// Use Math.floor(Math.random()) for port generation, replacing _.random
service.listen(Math.floor(Math.random() * 1000) + 1024)

setInterval(() => {
  serverLink.announce('rpc_test', service.port, {})
}, 1000)

service.on('request', (rid, key, payload, handler) => {
  console.log(`Server received request for '${key}' with payload: '${payload}'`)
  handler.reply(null, 'world')
})

console.log(`RPC Server listening on port ${service.port} and announcing 'rpc_test'`)

// RPC Client
const clientLink = new Link({
  grape: 'http://127.0.0.1:30001'
})
clientLink.start()

const peerClient = new PeerRPCClient(clientLink, {})
peerClient.init()

peerClient.request('rpc_test', 'hello', { timeout: 10000 }, (err, data) => {
  if (err) {
    console.error('Client error:', err)
    process.exit(-1)
  }
  console.log(`Client received data: '${data}'`) // world
  // In a real application, you might want to stop links gracefully
  // clientLink.stop()
  // serverLink.stop()
  // process.exit(0)
})

console.log('RPC Client sending request to \'rpc_test\' service...')

view raw JSON →