The simplest way to do interprocess communication on one or more machines using promises
npm install multicast-ipcjs
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.
$3
* 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:
`sh
npm install multicast-ipc
`
API Documentation
* CommApi
* new CommApi(socket)
* .broadcast(message) ⇒ Promise
* .repeatFor(count, fn) ⇒ Promise
* .repeatWhile ⇒ Promise
* .send(message, port, ipAddress) ⇒ Promise
* .unbind() ⇒ Promise
* [.waitForMessage([filter])](#CommApi+waitForMessage) ⇒ Promise
* multicastIpc
* ..apiCallback : function
* [..withSocket([port], [multicastAddress], callback)](#multicastIpc.withSocket) ⇒ Promise
-----
Classes
CommApi
-----
$3
API Helper Object has convenience functions for implementing your custom communications protocol.
| Param |
| --- |
| socket |
$3
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
`js
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!');
};
});
`
-----
$3
Repeat a set of commands for a specific number of timesFulfil: 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 |$3
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 |
$3
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
`js
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 |
$3
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
-----
$3
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
`js
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
-----
$3
This API callback is where you would implement your custom communication protocol.Since: 1.0.0
| Param | Type | Description |
| --- | --- | --- |
| api | CommApi | API Helper Object |
$3
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
`js
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).