The transport for freebird REQ/RSP/IND message transmission
This module is the abstract class for developers to create their own transportation to communicate with freebird framework. This class inherits from EventEmitter which will emit a 'message'
event when a message arrives.
- In this document,
transp
will be used to denote the instance of this class. - In the following methods, the argument
msg
must be an object in the shape of{ clientId, data }
, where thedata
property is mandatory and should be a string or a buffer, and theclientId
property is optional and should be a string or a number if given. One can attach an identifier, like a client id, tomsg.clientId
for message multiplexing.
To have a valid transp
, two things must be done by the implementer.
- Must implement the
transp._send(msg, callback)
method on the transport instance. - Must call the
transp.receive(msg)
method to let the transport instance know that there a message comes in. Callingtransp.receive(msg)
will induce a'message'
event triggered on the transport instance.
To use the transport object:
- Call
transp.send(msg, callback)
to send message out. It wil throw if_send()
was not provided by the implementer. - Listen to
'message'
event to receive messages.
- Constructor
- Implementer provides
- Implementer calls
- User calls
- User listens to events
Create the transport instance.
Arguments:
- none
Returns:
- (Object):
transp
, instance of this class
Examples:
var Transport = require('freebird-transport');
var transp = new Transport();
The implmentation of sending out the message.
Arguments:
msg
(Object): The message to trasmit out is a string or a buffer attached todata
property of this object.callback
(Function):function (err, bytes) { ... }
. This err-first callback should be called after message sent off. The argumentbytes
tells how many bytes were sent.
Returns:
- none
Examples:
var transp = new Transport();
transp._send = function (msg, callback) {
var bytes;
if (typeof msg.data === 'string')
msg.data = new Buffer(msg.data);
if (!Buffer.isBuffer(msg.data))
return setImmediate(callback, new TypeError('msg.data should be a string or a buffer'));
bytes = msg.data.length;
// ... implemention of message sending
// Finally, call callback
callback(null, bytes);
};
The implmentation of broadcasting the message. This is optional, it will use transp.send(msg, callback)
internally by default if implementation is not given. This broadcasting method is used to send an indication to multiple remote clients.
Arguments:
msg
(Object): The message to broadcast out is a string or a buffer attached todata
property of this object.callback
(Function):function (err, bytes) { ... }
. This err-first callback should be called after message sent off. The argumentbytes
tells how many bytes were sent.
Returns:
- none
Examples:
var transp = new Transport();
transp._broadcast = function (msg, callback) {
var bytes;
if (typeof msg.data === 'string')
msg.data = new Buffer(msg.data);
if (!Buffer.isBuffer(msg.data))
return setImmediate(callback, new TypeError('msg.data should be a string or a buffer'));
bytes = msg.data.length;
// ... implemention of message broadcasting
// Finally, call callback
callback(null, bytes);
};
Call this method to send the message off.
Arguments:
msg
(Object): The message to trasmit out must be a string or a buffer which should be attached todata
property of this object.callback
(Function):function (err, bytes) { ... }
. Get called after message sent off. The argumentbytes
tells how many bytes were sent.
Returns:
- none
Examples:
var transp = new Transport();
// assume transp._send was implemented
// call transp.send() to send message
transp.send({ data: 'Hello World' }, function (err, bytes) {
if (err)
console.log(err);
else
console.log(bytes + ' bytes were sent')
});
Call this method to broadcast the message.
Arguments:
msg
(Object): The message to trasmit out must be a string or a buffer which should be attached todata
property of this object.callback
(Function):function (err, bytes) { ... }
. Get called after message sent off. The argumentbytes
tells how many bytes were sent.
Returns:
- none
Examples:
var transp = new Transport();
transp.broadcast({ data: 'Hello World' }, function (err, bytes) {
if (err)
console.log(err);
else
console.log(bytes + ' bytes were sent')
});
The Implemntor should call this method to inform the message arrival.
Arguments:
msg
(Object): This must be an object with adata
property that holds the received message.callback
(Function):function (err) { ... }
. Optional. Get called after message sent off.
Returns:
- none
Examples:
var transp = new Transport();
// Implemntor calls transp.receive() when message arrives
foo.on('data', function (data) {
transp.receive({ data: data });
});
The user can listen to the 'message'
event to receive the message.
Arguments of the listener
msg
(Object): This must be an object with adata
property that holds the received message of a string or a buffer.
Examples:
var transp = new Transport();
transp.on('message', function (msg) {
console.log(msg.data.toString());
});
The implementer can listen to the 'unhandledMessage'
event to receive the message that is not processed by the freebird.
Arguments of the listener
msg
(Object): This must be an object with adata
property that holds the received message of a string or a buffer.
Examples:
var transp = new Transport();
transp.on('unhandledMessage', function (msg) {
console.log('Message not processed by freebird: ' + msg.data.toString());
});
var net = require('net'),
Transport = require('freebird-transport');
var transp, client;
transp = new Transport();
server = net.createServer(function (c) {
client = c;
client.on('end', function () {
client = null;
});
// Message received
client.on('data', function (data) {
transp.receive({ data: data });
});
});
server.listen(4321, function () {
console.log('TCP server starts');
});
// Implementaion of _send
transp._send = function (msg, callback) {
var bytes;
if (typeof msg !== 'object')
return setImmediate(callback, new TypeError('msg should be an object'));
if (typeof msg.data === 'string')
msg.data = new Buffer(msg.data);
if (!Buffer.isBuffer(msg.data))
return setImmediate(callback, new TypeError('msg.data should be a string or a buffer'));
bytes = msg.data.length;
if (!client)
return setImmediate(callback, new Error('No client connected'));
client.write(msg.data);
setImmediate(callback, null, bytes);
};
module.exports = transp;
var net = require('net'),
Transport = require('freebird-transport');
var transp, client;
transp = new Transport();
client = net.createConnection(4321, 'localhost', function () {
transp._send = function (msg, callback) {
var bytes;
if (typeof msg.data === 'string')
msg.data = new Buffer(msg.data);
if (!Buffer.isBuffer(msg.data))
return setImmediate(callback, new TypeError('msg.data should be a string or a buffer'));
bytes = msg.data.length;
if (!client)
return setImmediate(callback, new Error('No client created'));
client.write(msg.data);
setImmediate(callback, null, bytes);
};
});
client.on('end', function () {
client = null;
});
// Message received
client.on('data', function (data) {
transp.receive({ data: data });
});
module.exports = transp;