Welcome to the drachtio signaling resource framework, empowering nodejs/javascript developers to build highly-scalable SIP application servers -- without requiring a Ph.D in SIP or VoIP :)
drachtio is an open-source, nodejs-based ecosystem for creating any kind of VoIP server-based application: registrar, proxy, back-to-back user agent, and many others. Furthermore, when coupled with the drachtio media resource function module, rich media-processing applications can be easily built as well.
Within the drachtio ecosystem, drachtio-srf is a high-level abstraction framework that sits on top of the connect-inspired drachtio library, and allows the developer to easily create and manage SIP Dialogs, without the burden of tending to the details of lower-level SIP transactions and messages.
Note: API documentation for drachtio-srf can be found here.
var app = require('drachtio')();
var Srf = require('drachtio-srf');
var srf = new Srf(app) ;
// connect to drachtio server
srf.connect({..}) ;
srf.invite( function(req, res) {
// respond to incoming INVITE request by creating a user agent server dialog
srf.createUasDialog( req, res, {
localSdp: myLocalSdp,
headers: {
'Server': 'drachtio-srf Server'
}
}, function(err, dialog) {
if( err ) { throw err ; }
console.log('created user-agent server dialog: ', JSON.stringify(dialog)) ;
// set up dialog handlers
dialog.on('destroy', onCallerHangup) ;
}) ;
function onCallerHangup(msg) {
console.log('caller hung up, incoming BYE message looked like this: ', msg) ;
}
Note: drachtio-srf applications require a network connection to a drachtio server process that sits in the VoIP network and handles the low-level SIP messaging.
npm install drachtio-srf --save
First, create a drachtio "app". This contains the middleware stack and core message routing functions. Next, create a new instance of the drachtio signaling resource framework, passing the drachtio app that you just created.
var drachtio = require('drachtio') ;
var app = drachtio();
var Srf = require('drachtio-srf');
var srf = new Srf(app) ;
Similar to connect, drachtio supports the concept of middleware with the 'use' method. (The 'use' method may equivalently be called on the 'srf' instance, or the underlying 'app').
var rangeCheck = require('range_check');
...
srf.use(function (req, res, next) {
if( !rangeCheck.inRange( req.source_address, config.authorizedSources) ) {
return res.send(403) ;
}
next() ;
}) ;
Middleware can optionally be mounted only for specific SIP request types (methods) by specifying the method type (lower-cased) as an optional first parameter.
srf.use('register', parseRegister) ;
There are special cases of "error-handling" middleware. There are middleware where the function takes exactly 4 arguments. Errors that occur in the middleware added before the error middleware will invoke this middleware when errors occur.
srf.use(function (err, req, res, next) {
// an error occurred!
});
The drachtio server process provides the actual sip processing engine that can be controlled by one or more drachtio clients. Therefore, a drachtio-srf application must initially invoke the "connect" method on the srf instance (or, equivalently, on the underlying drachtio "app" object) to establish a connection to the drachtio server process in order to receive events (e.g. SIP messages) as well as send requests.
The application may either provide a callback to the "connect" call, or may listen for the "connect" event in order to determine whether/when a connection has been achieved.
srf.connect({
host: {ip address to connect to},
port: {port to connect to},
secret: {shared secret client must provide to authenticate to drachtio server}
}, function(hostport) {
console.log('connected to server listening for SIP messages on %s': hostport) ;
}) ;
// or, instead of callback
srf.on('connect', function(err, hostport){
if( err ) throw err ;
console.log('connected to server listening for SIP messages on %': hostport) ;
}) ;
At this point, your application is ready to start interacting with a VoIP/SIP network; generating or receiving SIP requests and creating dialogs. The relevant methods on the 'srf' instance are:
Once you have created a dialog, you will want to be able to respond to events as well as exert control over the dialog by calling methods.
- 'destroy' - fired when the remote end has sent a BYE request (i.e., the remote end has hung up). No action is required in the associated callback: this is a notification-only event.
- 'refresh' - fired when the remote end has sent a refreshing re-INVITE. No action is required in the associated callback: this is a notification-only event.
- 'modify' - fired when the remote end has sent a re-INVITE with a modified session description (i.e. SDP). drachtio request and response objects are provided to the event handler, and the application must respond to the re-INVITE by invoking the 'res.send' method.
- 'info', 'notify', 'refer', 'update' -- fired when the remote end has sent a request within the dialog of the specified request type. drachtio request and response objects are provided to the event handler, and the application must respond to the re-INVITE by invoking the 'res.send' method. (Note: if the application does not register a listener for this class of event, a 200 OK with an empty body will automatically be generated in response to the incoming request).
- destroy - terminates the dialog (i.e. sends a BYE to the far end)
- modify - modifies the dialog media session; either placing or removing the call from hold, or re-INVITING the far end to a new media session description
- request - send a request within a dialog (e.g. INFO, NOTIFY, etc)
It is a common requirement for any SIP network element to be able to generate cdrs. The drachtio server generates 'attempt', 'start', and 'stop' cdrs, and drachtio-srf applications can listen for associated cdr events:
- cdr:attempt events are generated whenever an INVITE is received from the network or generated by an application. In other words, there will be an attempt cdr for every call attempt handled by the drachtio server.
- cdr:start events are generated when a call is successfully connected (i.e. a 200 OK response to an INVITE is received or generated).
- cdr:stop events are generated when a call attempt concludes. Note that when a call is rejected (i.e. a non-success final response) a cdr:stop event is generated; alternatively, when a connected call is terminated a cdr:stop event will also be generated.