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.
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.
- 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
Install using npm:
npm install multicast-ipc
-
- new CommApi(socket)
- .broadcast(message) ⇒
Promise
- .repeatFor(count, fn) ⇒
Promise
- .repeatWhile ⇒
Promise
- .send(message, port, ipAddress) ⇒
Promise
- .unbind() ⇒
Promise
- .waitForMessage([filter]) ⇒
Promise
-
- ..apiCallback :
function
- ..withSocket([port], [multicastAddress], callback) ⇒
Promise
- ..apiCallback :
API Helper Object has convenience functions for implementing your custom communications protocol.
Param |
---|
socket |
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!');
};
});
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 |
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 |
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 |
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
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. |
This API callback is where you would implement your custom communication protocol.
Since: 1.0.0
Param | Type | Description |
---|---|---|
api | CommApi |
API Helper Object |
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
});
Please submit all issues and pull requests to the avishnyak/multicast-ipc repository!
Run tests using npm test
(coming soon).
If you have any problem or suggestion please open an issue here.