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-ipc-lib

v1.1.4

Published

Enables creation and consumption of Unix domain socket based IPC channels between Node.js apps using JSON-RPC 2.0 as a protocol.

Downloads

24

Readme

JSON IPC

Build Status Coverage Status

This library exists to facilitate creation and consumption of Unix domain socket based interprocess communication channels that opinionatingly use JSON-RPC 2.0 as a communication protocol. This library takes care of the plumbing and error handling and provides a simple interface to speed up development.

Getting Started

Install

npm install --save json-ipc-lib

Create a server

Below is an example where we create a file named server.js and populate it with the following code (available at ./examples/server.js):

import * as ipc from 'json-ipc-lib';

/**
 * The name of this object will act as a namespace for
 * the method argument that is provided when consuming
 * the server. This object can have multiple children
 * and unlimited hiearchy.
 **/
const services = {
  hello : (value = 'olleh') => value
};

const server = new ipc.Server(
  '/tmp/my-server.sock',
  { services });

// begin listening for messages
server.listen();

In a terminal window, we run as follows:

$ DEBUG=json-ipc node server.js

Create a client

Next up, we create an example of consuming the server from the example above. We create a file named client.js and put the following code in it (available at ./examples/client.js):

Note: The following code demonstrates several examples of consuming the Server instance.

import 'babel-polyfill';
import 'source-map-support/register';

import * as ipc from '../../dist';

(async () => {
  // create a client for server.js
  const client = new ipc.Client('/tmp/example-ipc-server.sock');

  /**
   * call the method conveniently (applies JSON-RPC formatting)
   * - this example is using async/await
   **/
  try {
    let convenient = await client.call(
      'services.hello',
      'convenient example string');

    console.log(
      'result from convenient client.call: %s',
      convenient);
  } catch (ex) {
    console.error(
      'error from convenient client.call: %s',
      ex.message,
      ex);
  }

  /**
   * call the method verbosely (send JSON-RPC formatted message)
   * - this example is using a traditional callback
   **/
  client.call({
    id : Date.now(),
    jsonrpc : '2.0',
    method : 'services.hello',
    params : ['verbose example string']
  }, (err, verbose) => {
    if (err) {
      console.error(
        'error from verbose client.call: %s',
        err.message,
        err);

        return;
    }

    console.log(
      'result from verbose client.call: %s',
      verbose);
  });

  /**
   * call the method conveniently with no arguments
   * - this example is using a Promise
   **/
  client
    .call('services.hello')
    .then((noArguments) => console.log(
      'result when passing no arguments to client.call: %s',
      noArguments))
    .catch((ex) => console.error(
      'error when passing no arguments to client.call: %s',
      ex.message,
      ex));
})();

In a separate terminal window, we run as follows:

$ DEBUG=json-ipc node client.js
  json-ipc new JSON-IPC Client: /tmp/example-ipc-server.sock +0ms
  json-ipc writing message to socket connection: '{"jsonrpc":"2.0","method":"services.hello","params":["convenient example string"],"id":1501772950481}' +6ms
result from convenient client.call: convenient example string
  json-ipc writing message to socket connection: { id: 1501772950505, jsonrpc: '2.0', method: 'services.hello', params: [ 'verbose example string' ] } +22ms
  json-ipc writing message to socket connection: '{"jsonrpc":"2.0","method":"services.hello","params":[],"id":1501772950506}' +2ms
result from verbose client.call: verbose example string
result when passing no arguments to client.call: olleh

Documentation

Usage Note: each asynchronous method on both the Client and Server instances can be used with either a standard callback as the last argument, or can be used as a Promise or with an await statement in an async method.

Client

Constructor: new ipc.Client(path, [options])

Creates a new instance of a Client that can be used to communicate with a Server instance that is listening on another process.

  • path - String, value is required (i.e. /var/run/my-service.sock): String path on the file system to the location of the Unix domain socket file (or named pipe) that is being used by an active Server instance.
  • options - Object, value is optional:
    • timeout - Number, defaults to 5000: The amount of time, in milliseconds, before the call method will timeout (a timeout results in an error response).
import { Client } from `json-ipc-lib`;

const client = new Client('/var/run/myserver.sock', { timeout : 10000 });

#call

Usage: client.call(method, [...args])

Call a method that is exposed for remote procedure call by the Server instance to which the Client is connected (via the path parameter provided to the constructor). This method accepts either a JSON-RPC 2.0 Request Object directly as the first argument or can be used to build the JSON-RPC 2.0 request dynamically when the method parameter is the String value name of the remote method target.

  • method - String or Object, value is required (i.e. services.hello): String name of remove service method to execute or optionally a JSON-RPC 2.0 compliant message that defines the id, method and params for the remote procedure call to be executed.
  • args - Array, value is optional: a list of arguments to provide to the remote method being executed. If the last value in the Array provided is a function, it is executed as a callback using the signature function (err, result) { }.
import { Client } from `json-ipc-lib`;

const client = new Client('/var/run/myserver.sock', { timeout : 10000 });

export default (async () => {
  let myResult = await client.call('myserver.remote.addNumbers', 100, 100);
  console.log(myResult);
})();

Server

Constructor: new ipc.Server(path, methods, [options])

Creates a new instance of a Server that exposes various methods available for remote procedure call from other processes. The Server will create a Unix domain socket handle at the specified path and will automatically clean the handle on server exit.

  • path - String, value is required (i.e. /var/run/my-service.sock): String path on the file system to the location of the Unix domain socket file (or named pipe).
  • methods - Object, value is required (i.e. { services : { lowerCaseEcho : (val) => val.toLowerCase() } }): An object, that may optionally have additional sub-objects, that maintains a list of remote methods available for execution. In the example, this field is an Object named services with a single function named lowerCaseEcho - this example translates to a JSON-RPC 2.0 method value of services.lowerCaseEcho. Each method must return synchronously or return a Promise when asynchrounous. At this time, callback methods are not supported - to utilize these, they need to be wrapped in Promise objects prior to being exposed via the Server instance.
  • options - Object, value is optional:
    • cleanHandleOnListen - (Boolean, defaults to true): Ehen true, the #listen() method will attempt to remove the Unix domain socket handle prior to creating a new one for listening
    • excludedMethods - (Array, defaults to []): My contain a list of strings that filter which methods are available for remote execution - this may come in handy when exposing an entire module, but there is a desire to hide certain functions from remote consumers.
import { Server } from `json-ipc-lib`;

const server = new Server(
  '/var/run/myserver.sock',
  {
    myserver : { // namespace `myserver`
      remote : { // namespace `myserver.remote`
        addNumbers : (...args) => new Promise((resolve, reject) => {
          let total = args.reduce((sum, value) => {
            return sum + value;
          }, 0);

          if (isNaN(total)) {
            return reject(new Error('result is not a number'));
          }

          return resolve(total);
        })
      }
    }
  });

#close

Usage: server.close([callback])

Can be used to close an actively listening Server instance. If the Server instance is not listening for connections, this method will return an Error

  • callback - function, value is optional (i.e. function (err) { }): When provided, the method will execute the callback upon server close. When omitted, the method will return a Promise object.
import { Server } from `json-ipc-lib`;
import remote from './remote.js';

const server = new Server(
  '/var/run/myserver.sock',
  {
    myserver : {
      remote
    }
  });

export default (async () => {
  try {
    await server.close();
  } catch (ex) {
    console.error(ex);
  }
})();

#getConnections

Usage: server.getConnections([callback])

Returns the number of active connections to the server.

  • callback - function, value is optional (i.e. function (err, count) { }): When provided, the method will execute the callback upon completion. When omitted, the method will return a Promise object.
import { Server } from `json-ipc-lib`;
import remote from './remote.js';

const server = new Server(
  '/var/run/myserver.sock',
  {
    myserver : {
      remote
    }
  });

export default (async () => {
  try {
    await server.listen();

    let count = await server.getConnections();

    console.log('connected clients: %d', count);
  } catch (ex) {
    console.error(ex);
  }
})();

#listen

Usage: server.listen([callback])

Allows the Server instance to begin listening for connections. At this step, the server will create a new handle at the supplied path as a Unix domain socket.

  • callback - function, value is optional (i.e. function (err) { }): When provided, the method will execute the callback once the Unix domain socket is created and the server is actively listening for new connections. When omitted, the method will return a Promise object.
import { Server } from `json-ipc-lib`;
import remote from './remote.js';

const server = new Server(
  '/var/run/myserver.sock',
  {
    myserver : {
      remote
    }
  });

export default (async () => {
  try {
    await server.listen();
  } catch (ex) {
    console.error(ex);
  }
})();

event: close

Emitted once the server is closed and no longer listening for new connections.

event: connection

Emitted when a new connection is established with the Server isntance.

  • socket - net.Socket: The socket connected to the Server instance.

event: error

Emitted when an Error is encountered on the Server instance after listening has begun.

  • error - Error: The Error that occurred.

event: listening

Emitted once the Server instance is listening for new connections.

event: request

Emitted each time a new JSON-RPC 2.0 request is received and successfully parsed on the server.