Microsoft Lync and Skype for Business have a rich set of .NET APIs which make it easy to extend the platform and integrate it with other applications. This blog helps explain how to use those APIs.

Minimizing performance impact from managed SIP applications

Posted: January 4th, 2012 | Author: | Filed under: Lync Development, MSPL | Tags: , , , | 3 Comments »

The Managed SIP Application API, which I discussed in the previous post, allows you to manipulate the content and routing of SIP messages in some potentially very useful ways by running an application on a Front End Server. However, when the volume of messages is very large, dispatching them to managed code can have a significant effect on performance. For managed code applications that simply monitor messages, and don’t modify them or change the routing, there is a way to mitigate this performance impact by sending the message details to the application from the MSPL script in a sort of “fire-and-forget” mode, using the DispatchNotification method.

Normally, when you dispatch a message to a managed SIP application using the Dispatch method in MSPL, the application “takes over” the routing of the message from that point forward. Execution of the MSPL script stops, and the application must proxy the request or response in some way in managed code. The DispatchNotification method, on the other hand, simply passes one or more pieces of information to the application, and then the execution of the MSPL script continues. The MSPL script remains responsible for routing the message or responding to it. This means that the managed code does not affect the speed of the message routing in any way.

Here’s an example of an MSPL script that uses DispatchNotification:

<?xml version="1.0"?>
<r:applicationManifest
 r:appUri="http://mspl.greenl.ee/LogSample"
 xmlns:r="http://schemas.microsoft.com/lcs/2006/05">

<r:requestFilter methodNames="MESSAGE,INVITE,ACK,BYE"
                 strictRoute="true"
                 domainSupported="false"/>

<r:responseFilter reasonCodes="ALL"/>

<r:splScript><![CDATA[
if (sipRequest)
{
    DispatchNotification("OnRequest", sipRequest.Method);
    ProxyRequest();
}
else {
    DispatchNotification("OnResponse", sipResponse.StatusCode);
    ProxyResponse();
}
]]></r:splScript>
</r:applicationManifest>

A couple of things to note here: first, the script calls ProxyRequest or ProxyResponse after dispatching the notification, effectively routing the message to where it was going to go before the MSPL script got its hands on it. This is an important difference from the sample script from the previous post. Another difference is that the second parameter of DispatchNotification is required (for Dispatch, it’s optional). The reason is that the only information that gets passed to the managed SIP application is the parameters that you specify when calling DispatchNotification. The first parameter is the method name to call in the managed code, and all the subsequent parameters (you can have as many as you want) contain information to be passed to the method as part of the event arguments.

Here’s a class that you might use as your handler in the managed SIP application:

using Microsoft.Rtc.Sip;

public class Logger
{
    public void OnRequest(object sender,
        Microsoft.Rtc.Sip.NotificationReceivedEventArgs e)
    {
        foreach (var o in e.Parameters)
        {
            System.Console.WriteLine(o.ToString());
        }
    }

    public void OnResponse(object sender,
        NotificationReceivedEventArgs e)
    {
        foreach (var o in e.Parameters)
        {
            System.Console.WriteLine(o.ToString());
        }
    }
}

This is a trivially simple example, but of course you could do much more ambitious things here, cross-referencing with in-memory state, writing to a database, etc. The main thing to note is that these methods use a different event arguments object: NotificationReceivedEventArgs. This is important; you need to use a different method for DispatchNotification from the one you use for Dispatch, because the event arguments are different. This one does not give you access to an object representing the message. All you have is a collection called Parameters, which contains all of the data you passed in the parameters of DispatchNotification. So you need to pick out the information you need in the MSPL script.

In this case, I’m simply writing the method name (for requests) and the status code (for responses) to the console, but you can pass more parameters to get other information from the message to do things like call detail reporting, logging, auditing, and so forth. This may already be clear, but I want to point out also that you can mix Dispatch and DispatchNotification in a single MSPL script and a single managed SIP application. You just need to create separate methods in the managed code portion. So, your script can send notifications for messages where the application just needs to know about them, but doesn’t need to make any changes (perhaps to maintain its own session state information); and can use Dispatch when the application actually needs to take action. This helps minimize the effect that your managed SIP application has on the performance of message routing in the Lync environment.


3 Comments on “Minimizing performance impact from managed SIP applications”

  1. 1 Thomas said at 8:55 am on January 22nd, 2015:

    Great article 🙂 Is it ok to remove ProxyRequest() and ProxyResponse() if I include the tag ?

  2. 2 Thomas said at 8:56 am on January 22nd, 2015:

    Tagname disappeared.. .. tag proxyByDefault with attribute action=true

  3. 3 Navya said at 7:33 am on April 25th, 2016:

    Hi Michael,

    I am trying to pass few parameters (using DispatchNotification) to my Managed SIP API when the incoming request is REFER. I want the following fields from, to, via, callid, cseq,
    referred-by and refer-to.

    This is my MSPL code:

    if (sipRequest.Method == “REFER”)
    {
    via = GetHeaderValues(“Via”);
    callid = GetHeaderValues(“Call-ID”);
    cseq = GetHeaderValues(“CSeq”);
    referto = GetHeaderValues(“Refer-To”);
    referredby = GetHeaderValues(“Referred-By”);

    DispatchNotification(“ProcessRefer”, sipRequest.Method, sipRequest.RequestUri, sipRequest.From, sipRequest.To, via, callid, cseq, referto, referredby);
    ProxyRequest(“”);
    }

    And my manged SIP API code is as given below:

    public void ProcessRefer(object sender, NotificationReceivedEventArgs e)
    {
    Console.WriteLine(“Processing refer”);

    object[] param = e.Parameters;

    foreach (var o in param)
    Console.WriteLine(“{0}”, param.ToString());
    //this is just temporary code to confirm the values are being passed correctly
    }

    Method, requesturi, from and to values are being printed where as via, callid, cseq, referto, referred-by are printed as System.Object[].
    Is there any other way to access the same?

    Navya


Leave a Reply

  • Note: Comment moderation is in use because of excessive spam. Your comment may not appear immediately.

  •