Skip to content

A promise-based IPC implementation that uses dgram multicast under the hood

License

Notifications You must be signed in to change notification settings

avishnyak/multicast-ipc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Multicast IPC

npm

Dealing with sockets, events and state machines is hard. Communicating between your processes should be fun not hard. This module aims to make that happen by abstracting away some of the complexity and using promises to chain together communication states.

Example

var ipc = require('multicast-ipc');

ipc.withSocket(function (api) {
  // API is a handy class that has lots of helper functions on it

  return api.broadcast('I am online!')
     .then(api.waitForMessage())
     .timeout(5000) // from Bluebird
     .then(function (message) {
         // message is a Buffer here
         var cmd = message.toString();

         if (cmd === 'ping') {
            return api.broadcast('pong');
         } else {
            return api.unbind();
         }
     });
});

Note: This is still under active development and APIs may change. Every effort will be made to maintain backwards compatibility.

Benefits

  • A chainable promise-based api
  • Abstracts all the socket work and resources via promises
  • Allows a pub/sub inter-process communication
  • Easily move communication from same machine to separate machines
  • Compatible with Windows, Linux and OS X
  • Requires a network to be present - don't rely on this IPC method for local-only programs

Installation

Install using npm:

npm install multicast-ipc

API Documentation


Classes

CommApi
multicastIpc

CommApi


new CommApi(socket)

API Helper Object has convenience functions for implementing your custom communications protocol.

Param
socket

commApi.broadcast(message) ⇒ Promise

Broadcast a message to all listeners.

Listeners will need to connect to the same port and multicastAddress as the sender to receive messages.

Fulfil: No value. The buffer is safe to reuse now.
Reject: Error err - Error returned from socket
Since: 1.0.0

Param Type Description
message Buffer | string Message to send

Example

var ipc = require('multicast-ipc');

// Announcer BOT will tell everyone when someone joins the room!
ipc.withSocket(function (api) {
  function isJoinMessage(message, rinfo) {
      return message.toString().substr(0, 5) == 'join:';
  }

  return api.waitForMessage(isJoinMessage)
            .map(function (req) {
                // Send a message to all listeners
                
                return api.broadcast('Player ' + req.message.toString().substr(5) + ' has entered the arena!');
            };
});

commApi.repeatFor(count, fn) ⇒ Promise

Repeat a set of commands for a specific number of times

Fulfil: number lastValue - The last value of the for..loop (always 0)
Reject: Error err - Error thrown from the fn function
Since: 1.0.0

Param Type Description
count number The number of times that fn should be called
fn function The function that should be repeated

commApi.repeatWhile ⇒ Promise

Repeat a certain chain of commands until the specified condition is met. This is the equivalent of a while loop.

The condition function is used to decide whether to continue looping or stop. It receives the last value from the action function as input and should return true to continue the loop or false to stop.

The action function contains the body of the loop. This is typically an entire back and forth interaction of the protocol using broadcast, send and waitForMessage functions. The end result should be a promise that resolves to a value which will be passed into the condition function.

Fulfil: * The latest lastValue
Reject: Error err - Error thrown by either the condition function or the action function
Since: 1.0.0

Param Type Description
condition function A callback function that receives the "lastValue" and returns true to continue repeating
action function A callback function that must return a promise
lastValue * This is the first "lastValue" that will be passed to the condition function

commApi.send(message, port, ipAddress) ⇒ Promise

Send a message directly to a port/ip address.

This function can be used for 1:1 communication as well as for group messaging if the IP address happens to be one that is in the multicast range.

If the value of address is a host name, DNS will be used to resolve the address of the host which will incur at least one processTick delay. If the address is an empty string, '127.0.0.1' or '::1' will be used instead.

Fulfil: No value
Reject: Error err - Error from sending the command
Since: 1.0.0

var ipc = require('multicast-ipc');

// Welcome BOT will welcome new players
ipc.withSocket(function (api) {
  // Send a message to all listeners

  function isJoinMessage(message, rinfo) {
      return message.toString().substr(0, 5) == 'join:';
  }

  return api.waitForMessage(isJoinMessage)
            .map(function (req) {
                // Send a direct message as a 'reply' back to the process that sent the original message

                return api.send('Welcome ' + req.message.toString().substr(5) + '!', req.port, req.address);
            };
});
Param Type Description
message Buffer | string The message to send
port number UDP port to send data to
ipAddress string Destination hostname or IP address

commApi.unbind() ⇒ Promise

Unbind socket. No more communication can be done through this promise chain after this.

Fulfil: Socket closed successfully
Reject: Error err - Socket could not be closed
Since: 1.0.0


commApi.waitForMessage([filter]) ⇒ Promise

Wait for a specific message. The optional filter function is called for every message that is received. If the filter function returns true, the promise is resolved with that value.

Fulfil: { address: string, family: string, port: number, message: Buffer } message - The message that was received
Reject: Error err - Error thrown from the filter function
Since: 1.0.0

var ipc = require('multicast-ipc');

// Logger BOT will log incoming messages
ipc.withSocket(function (api) {
  function isJoinMessage(message, rinfo) {
      return message.toString().substr(0, 5) == 'join:';
  }

  return api.waitForMessage(isJoinMessage)
            .map(function (req) {
                console.log('Audit Log: %s:%d - %s', req.address, req.port, req.message.toString());
            };
});
Param Type Description
[filter] function Each received message is passed into the filter function.

multicastIpc


multicastIpc..apiCallback : function

This API callback is where you would implement your custom communication protocol.

Since: 1.0.0

Param Type Description
api CommApi API Helper Object

multicastIpc..withSocket([port], [multicastAddress], callback) ⇒ Promise

Initialize a socket. Listens to messages, allows sending messages and automatically cleans up after itself.

The callback function will be invoked after the socket is successfully set up. An api object will be passed to the callback which has utility functions that help in creating the application-layer communication protocol.

Fulfil: * Result of the last item returned from the callback
Reject: Error Error from binding the socket
Since: 1.0.0

Param Type Default Description
[port] number 61088 Datagram port to listen on
[multicastAddress] string "224.0.2.1" Multicast address to group senders/listeners
callback apiCallback Function that will be called with the communication api object

Example

var ipc = require('multicast-ipc');

ipc.withSocket(function (api) {
  // The API object contains helper methods for implementing your own IPC protocol
  
  return api.broadcast('node:online')
            .then(api.unbind);  // This is optional (the library automatically handles resources
});

Contributing

Please submit all issues and pull requests to the avishnyak/multicast-ipc repository!

Tests

Run tests using npm test (coming soon).

Support

If you have any problem or suggestion please open an issue here.

About

A promise-based IPC implementation that uses dgram multicast under the hood

Resources

License

Stars

Watchers

Forks

Packages

No packages published