drachtio-srf
repository·main·Indexed 42 days ago
https://github.com/drachtio/drachtio-srfA Node.js framework for building SIP Server applications, providing high-level abstractions for proxying, B2BUA creation, and SIP request handling. It connects to a drachtio server to facilitate signaling operations and includes utilities for managing SIP Dialogs, handling authentication challenges via DigestClient, and implementing middleware for SIP requests and responses. Version 5.0.29.
What's inside drachtio-srf
- drachtio-srf is a Node.js framework designed for building SIP Server applications. It provides high-level abstractions for common SIP tasks such as proxying requests, creating Back-to-Back User Agents (B2BUAs), and sending manual SIP requests. It connects to a drachtio server to facilitate signaling operations.
Connect to a drachtio server
mainTo use
drachtio-srf, you must first instantiate theSrfclass and call theconnect()method with your server configuration. The configuration object requireshost,port, andsecret.const Srf = require('drachtio-srf'); const srf = new Srf(); srf.connect({ host: '192.168.32.5', port: 9022, secret: 'cymru' });Manage SIP session state with the Dialog class
mainThe
Dialogclass represents a SIP dialog and manages its state, media attributes, and lifecycle events. You do not instantiate this class directly; instead, it is returned bySrf#createUAC,Srf#createUAS, orSrf#createB2BUA.Key properties available on a
Dialoginstance:id: The unique identifier for the dialog.type: The type of dialog (e.g., 'uac' or 'uas').sip: An object containingcallId,localTag, andremoteTag.local: The local side of the session, containinguri,sdp, andcontact.remote: The remote side of the session, containinguriandsdp.onHold: A boolean indicating if the session is currently on hold.connected: A boolean indicating if the dialog is still active.
Dialog States and Directions
mainThe
Srfframework usesDialogStateandDialogDirectionconstants to represent the lifecycle and role of a SIP dialog.DialogState:
trying: Initial state.proceeding: Provisional responses received.early: Early media state.confirmed: Dialog established (e.g., 200 OK sent/received).terminated: Dialog ended normally.rejected: Dialog failed due to a rejection.cancelled: Dialog was cancelled (e.g., via CANCEL request).
DialogDirection:
initiator: The side that started the dialog (UAC).recipient: The side that received the request (UAS).
Handle SIP Messages and Requests
mainSIP interactions involve
SipMessage,SrfRequest, andSrfResponseobjects:SipMessage: The base interface containing raw data, headers, and methods toget,set, orhasheaders.SrfRequest: ExtendsSipMessagewith SIP-specific properties likemethod,callId,branch,sdp, anduri. It includes acancel()method.SrfResponse: ExtendsSipMessagewithstatus(e.g., 200) andreason(e.g., 'OK'). It includes asend()method to transmit the response to the client.
Handle SIP dialog events
mainThe
Dialogclass is anEventEmitterthat emits several events based on incoming SIP messages. When you attach a handler to these events, you are responsible for generating a SIP response using the providedres.send()method. If no handler is attached, the library automatically sends a200 OKfor most methods.Common Events:
destroy: Triggered when the dialog is torn down from the far end (e.g., receiving aBYE).modify: Triggered when the far end sends a re-INVITE. You must callres.send()to respond.refresh: Triggered when the far end sends a session refresh (notification only; no response required).hold/unhold: Triggered when the far end modifies the session to hold or unhold.info: Triggered when anINFOmessage is received.notify: Triggered when aNOTIFYmessage is received.options: Triggered when anOPTIONSmessage is received.update: Triggered when anUPDATEmessage is received.refer: Triggered when aREFERmessage is received.message: Triggered when aMESSAGEmessage is received.subscribe: Triggered when aSUBSCRIBErequest is received.ack: Triggered when anACKis received.
Manage a SIP Dialog
mainA
Dialogobject represents a SIP session (e.g., a call). It provides methods to interact with the session:modify(sdp, opts): Sends a re-INVITE or UPDATE to change session parameters like SDP.request(opts): Sends a new SIP request within the context of the dialog.destroy(opts): Terminates the dialog.on(event, callback): Listens for session events likeack,info,message,notify,refer, etc.
// Example: Modifying SDP in a dialog await dialog.modify('v=0\r\no=...'); // Example: Listening for a REFER event dialog.on('refer', (req, res) => { console.log('Received REFER'); });Initialize and connect a DrachtioAgent
mainTo use
drachtio-srf, you must instantiate aDrachtioAgentand connect it to a drachtio server. The agent acts as the primary interface for sending SIP requests and receiving SIP messages.When connecting, you must provide a
secretfor authentication and optionallytagsto identify the agent to the server. The agent uses a callback mechanism (passed to the constructor) to route incoming requests and responses to your application middleware.Common events to listen for include
connect,close, anderror.const DrachtioAgent = require('drachtio-srf').DrachtioAgent; // The callback passed to the constructor is the middleware handler const agent = new DrachtioAgent((req, res) => { // Handle incoming SIP requests here console.log('Received request:', req.method, req.uri); }); agent.connect({ host: '127.0.0.1', port: 9022, secret: 'your-secret', tags: ['my-agent'] }, (err) => { if (err) { console.error('Connection error:', err); return; } console.log('Connected to drachtio server'); });Create a Back-to-Back User Agent (B2BUA) with srf.createB2BUA()
mainThe
createB2BUA()method allows you to bridge two SIP legs (a User Agent Client and a User Agent Server). It is typically called within aninvitehandler.Parameters:
uri: The target SIP URI (e.g.,'sip:1234@10.10.100.1').req: The incoming SIP request.res: The incoming SIP response.options: An object containing configuration, such aslocalSdpBto provide local SDP.
Returns: Returns a Promise that resolves to an object containing
{uas, uac}. You should listen for the'destroy'event on both legs to ensure that when one side terminates, the other side is also hung up.srf.invite((req, res) => { srf.createB2BUA('sip:1234@10.10.100.1', req, res, {localSdpB: req.body}) .then(({uas, uac}) => { console.log('call connected'); // when one side terminates, hang up the other uas.on('destroy', () => { uac.destroy(); }); uac.on('destroy', () => { uas.destroy(); }); }) .catch((err) => { console.log(`call failed to connect: ${err}`); }); });Send manual SIP requests with srf.request()
mainYou can send arbitrary SIP requests using
srf.request(). This is useful for tasks like sendingOPTIONSpings.Parameters:
uri: The target SIP URI.options: An object containing themethod(e.g.,'OPTIONS') andheaders.callback: A callback function that receives(err, req).
Usage: Listen for the
'response'event on the returned request object to handle the SIP response.srf.request('sip:tighthead.drachtio.org', { method: 'OPTIONS', headers: { 'Subject': 'OPTIONS Ping' } }, (err, req) => { if (err) return console.log(`Error sending OPTIONS: ${err}`); req.on('response', (res) => { console.log(`Response to OPTIONS ping: ${res.status}`); }); });Proxy SIP requests with srf.proxyRequest()
mainYou can act as a SIP proxy by using
srf.proxyRequest(). This method takes an incoming request, a list of target destinations, and an optional configuration object. It returns a Promise that resolves with the results of the proxy operation.Options:
recordRoute: Boolean indicating if Record-Route should be used.followRedirects: Boolean indicating if redirects should be followed.provisionalTimeout: A string representing the timeout for provisional responses (e.g.,'2s').
Result Object: Resolves to an object containing:
finalStatus: The final SIP status code.finalResponse: The final SIP response object.responses: An array of intermediate responses.
srf.invite((req, res) => { srf.proxyRequest(req, ['sip.example1.com', 'sip.example2.com'], { recordRoute: true, followRedirects: true, provisionalTimeout: '2s' }).then((results) => { console.log(JSON.stringify(results)); // {finalStatus: 200, finalResponse:{..}, responses: [..]} }); });Configure the Srf instance
mainWhen connecting to a drachtio server, use the
SrfConfigobject to specify connection details. You can provide thehost,port,secretfor authentication, and an optionalloggerfunction for debugging.const config: Srf.SrfConfig = { host: '127.0.0.1', port: 9000, secret: 'your-secret', logger: (msg) => console.log(msg) };