Introduction to the UCMA API - Part 14 - the SERVICE message

Today we will cover a message type those of you more familiar with SIP may not know much about – the SERVICE request. Before writing this post, I attempted to research this message type on the Internet without success. Finally I just decided to look at the SIP RFC and noticed that this message type is not listed there. See the SIP RFC at https://www.ietf.org/rfc/rfc3261.txt. Given that there isn’t very much information around on this message type, I thought that others could be just as confused as I was.

 

I have already covered the SUBSCRIBE and NOTIFY messages. Imagine that I am interested in the current presence of a user – for instance whether that user is online or offline. One way I can accomplish this is by sending a SUBSCRIBE message to our server containing the user who’s presence I am interested in. When that presence changes, the server will send me a NOTIFY message informing me of the new state. But how does the server itself know that the state has changed?

 

That is the job of the SERVICE message. The client I am interested in will send a SERVICE message to the server indicating its new state, and the server in turn will send NOTIFY messages to all parties interested.

 

Unfortunately, as with SUBSCRIBE messages we can only implement this on the client. SERVICE messages are also automatically rejected with a 480 error code on the server. We will not permanently change the code in our client, but I will show you what code you would add in order to send a SERVICE request to our server. Below is the code for our SendServiceMessage method that will send a SERVICE message.

 

private void SendServiceMessage()

{

    RecordProgress("Sending SERVICE message");

    string message = "here";

    SipServiceRequest serviceRequest = new SipServiceRequest(_endPoint,

                                  new ContentType("text/plain"),

                                                            Encoding.UTF8.GetBytes(message));

    serviceRequest.BeginService(new AsyncCallback(ServiceMessageCallback), serviceRequest);

}

This message occurs outside the scope of our dialog so it does not require a SignalingSession. The SipServiceRequest class helps us send the message. To create our request we need our end point, the content type of the message, and the message itself. We then call BeginService to send the message. The following is our callback method.

 

private void ServiceMessageCallback(IAsyncResult ar)

{

    SipServiceRequest serviceRequest = ar.AsyncState as SipServiceRequest;

    SipResponseData response;

    try

    {

        response = serviceRequest.EndService(ar);

        RecordProgress("SERVICE message sent successfully.");

    }

    catch (FailureResponseException e)

    {

        if (e.ResponseData != null)

        {

            Error("The Notification could not be received by {0}; the SERVICE was rejected with error code {1}.",

                         Settings.OurServerName,

                         e.ResponseData.ResponseCode);

        }

        else

        {

            Error("The Notification could not be received by {0}; the SERVICE was rejected",

                  Settings.OurServerName);

        }

        return;

    }

    catch (OperationTimeoutException)

    {

        Error("The Notification could not be received by {0}; the SERVICE request timed out.",

              Settings.OurServerName);

        return;

    }

    catch (RealTimeException e)

    {

        Error("The Notification could not be received by {0}; Message: {1}.",

                     Settings.OurServerName,

                     e.Message);

        return;

    }

}

This is very similar to our SendMessage callback and just makes sure the message was sent. As with the SipSubscription class, you will probably find this very helpful when dealing with Microsoft Office Communications Server itself but admittedly it is of limited use when creating your own servers.

 

You may wonder in what exact Microsoft Office Communications Server scenarios this will be helpful. Because most of the internal messaging of Microsoft Office Communications Server is not public I will avoid discussing these features directly. If I find an area that is public information I will discuss it in a future post.

 

Part11.zip