npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

json-rpc-server-stream

v1.0.0

Published

JSON RPC 2.0 server implementation with streaming I/O and event driven API for endpoint implementers.

Downloads

4

Readme

JSON RPC Server Stream

JSON 2.0 RPC server implementation with streaming I/O and event driven API for endpoint implementers. For the corresponding client implementation see json-rpc-client-stream.

Line-delimited JSON

JSON is streamed with new line character \n as delimiter from the server, which enables sensible client side parsing even if several JSON encoded responses are streamed in the same chunk from the server. Several incoming JSON encoded requests or notification objects are also expected to be delimited with new line characters if sent in the same chunk.

For gereral info about new line encoded JSON, see http://jsonlines.org/.

JSON RPC 2.0 Architecture

The JSON RPC 2.0 protocol uses a client-server-architecture, in contrast to the peer-to-peer oriented 1.0 version, where peers act as both clients and server. However, it is still possible to use JSON RPC 2.0 in a peer-to-peer fashion.

Using JSON RPC 2.0 in a Peer-to-peer Fashion

A server and client pair must be installed on each node in order to use JSON RPC 2.0 in a peer-to-peer fashion. Additionally, full-duplex communication between node endpoint is required, for instance using WebSockets. The question then becomes: How to separate incoming requests from incoming responses?

This problem could be handled by the protocol implementation, since it is quite straight forward to separate well-formed requests from well-formed responses. Consequently, messages could be inspected by the implementation and either be handled as requests or as responses. However, such an approach is not optimal – It violates the idea of separation of concerns. Furthermore, there are malformed JSON RPC 2.0 messages, such as an empty array "[]", that cannot be distinguished as a malformed request that requires an error response or a malformed response that should be left unanswered.

A better approach when a JSON RPC 2.0 server and client on the same node share a common bidirectional channel is to multiplex and demultiplex (mux/demux) the transmission, so that each message only hits the intended endpoint implementation. The module mux-demux-stream can be used to achieve this.

Installation

npm install json-rpc-server-stream

Usage

Create a JSON RPC server stream and add event listeners for incoming requests or notifications.

Do some stream plumbing, such as: Readable connection stream -> RPC server -> Writable connection stream.

As mentioned above, it is recommended to pipe the streaming JSON RPC 2.0 server and client through a mux/demux before piping it to a channel stream if using JSON RPC 2.0 in a peer-to-peer fashion.

jsonRpcServerStream()

The module exports a factory function that returns a JSON RPC server stream instance, which is a duplex stream.

jsonRpcServerStreamInstance.rpc.on(event, listener)

Add listener for an RPC method. The listener takes a parameter argument and a reply argument. The reply argument is a callback that should be invoked with an error and a result if the RPC was a request. If the reply callback is provided with an error, the result argument must be left undefined. If the RPC was a notification (which should not be replied to) the reply callback is a noop.

Basic Example

The following examples shows the basic use cases for a JSON RPC 2.0 Server.

var jsonRpcServerStream = require('json-rpc-server-stream')();

// A request
jsonRpcServerStream.rpc.on('divide', function(params, reply) {
  if (params.denominator === 0) {
    return reply(new Error('Division by zero'));
  }

  reply(null, params.numerator / params.denominator);
});

// A notification
jsonRpcServerStream.rpc.on('log', function(params) {
  console.log(params);
});

getSomeReadableStreamSomehow()
  .pipe(jsonRpcServerStream)
  .pipe(getWritableStreamSomehow());

Advanced Example

The following example shows how to implement a JSON RPC 2.0 client and server in node.js where websockets are used as a shared bi-directional channel, with multiplexed and demultiplexed transmission. Additional modules ws, json-rpc-client-stream, websocket-connection-stream, and mux-demux-stream are used.

var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ port: 8080 });
var mux = require('mux-demux-stream');

wss.on('connection', function connection(ws) {
  var websocketConnectionStream = require('websocket-connection-stream')().attach(ws);
  var jsonRpcServerStream = require('json-rpc-server-stream')();
  var jsonRpcClientStream = require('json-rpc-client-stream')();

  mux(jsonRpcServerStream, jsonRpcClientStream)
    .pipe(websocketConnectionStream)
    .demux(jsonRpcServerStream, jsonRpcClientStream);

  jsonRpcServerStream.rpc.on('join', function(params, reply) {
    if (checkIfUserIsAllowedToJoinRoomSomehow(params.roomId, jsonRpcClientStream)) {
      placeJsonRpcClientStreamInARoomCollectionSomehow(params.roomId, jsonRpcClientStream);
      return reply(null, 'OK';
    }

    reply(new Error('Not allowed'));
  });

  jsonRpcServerStream.rpc.on('chat', function(params) {
    var jsonRpcClientStreams = getAllJsonRpcClientInstancesForRoomSomehow(params.to);

    jsonRpcClientStreams.forEach(function(jsonRpcClientStream) {
      jsonRpcClientStream.rpc.emit('chat', {
        from: params.from,
        message: params.message
      });
    });
  });
});

Related packages

Test

Run unit tests;

$ npm test

Create test coverage report:

$ npm run-script test-cov

License

MIT