Deliver SIP-based services to Java applications with SIP Servlet
IT and telecom are converging. Network-IT applications, typically data oriented, are merging with communication applications. The increasing number of Call Me buttons appearing on Webpages is an example of this integration. The SIP Servlet Specification brings a familiar programming model to Java developers for building converged applications. This article gives a step-by-step introduction on how to use SIP Servlet to build a simple echo chat service.
Session Initiation Protocol
Defined in Request for Comments 3261, SIP is a protocol for establishing, modifying, and terminating multimedia IP communication sessions. Figure 1 is a simple example of using SIP to establish a VoIP (voice-over Internet Protocol) call:
Figure 1. Typical SIP message flow in VoIP calls
All the white lines in Figure 1 represent the SIP communications. Caller sends a SIP INVITE request to invite the "callee" to establish a voice session. Callee first responds with a message that has a 180 status code to indicate the phone is ringing. As soon as phone is picked up, a response with a 200 status code is sent to the caller to accept the invitation. Caller confirms with an ACK message, and session is established. Once the session is established, the actual digitized voice conversation typically transmits via Realtime Transmission Protocol (RTP) with the session, as the red line in Figure 1 indicates. When the conversation ends, a SIP BYE request is sent, followed by a response with a 200 status code to confirm the session termination.
Here is an example of a SIP INVITE request and a response with a 200 OK status code:
SIP 200 OK response:
As you can see, the format of SIP resembles HTTP. However, when compared to HTTP, SIP is:
Responsible for session management. The actual multimedia content, such as instant messages, voice, and video, may or may not be transmitted via SIP.
- Asynchronous and stateful. For each SIP request, there could be multiple responses. This means the application has to process each SIP message within a proper state context.
- An application protocol that can run on both reliable and unreliable transport. Thus, the application must guarantee the message delivery with message retransmission and acknowledgement.
- A peer-to-peer protocol where there is no clear distinction between client and server. Either side must be able to send and receive requests and responses.
SIP-based services are SIP servers that offer services, such as message routing, to SIP endpoints, such as IP phones. For example, in Figure 2, the SIP registrar server and proxy server offer SIP registration and proxy services to help the SIP endpoints locate and communicate with each other.
message routing with SIP registrar and proxy server. Click on thumbnail to view full-sized image.
Figure 2 illustrates the following:
- Callee registers itself to the registrar server by sending a REGISTER request.
- The registrar server accepts the registration, which contains the callee's name address, by responding with a 200 OK status code.
- Caller requests to establish a communication session with callee by sending an INVITE request to the proxy server. The INVITE message's content typically contains the description of the communication session the caller wants to establish, such as media type, security, or IP address. The description is typically in Session Description Protocol (SDP) format.
- The proxy server looks up the registrar server to find out the callee's current address. Note that lookup is an implementation issue not part of SIP.
- The proxy server forwards the INVITE request from caller to callee based on its current address.
- Callee accepts the invitation by responding with a 200 OK status code. The 200 OK response to an INVITE request typically contains the description of the communication session that callee can establish with the caller.
- The proxy server forwards a 200 OK response from callee to caller.
- Caller confirms the session establishment by sending an ACK message to the proxy server. The ACK message may contain the final agreement on the session.
- In turn, the proxy server forwards the ACK to the callee. Thus, the three-way handshake is completed via the proxy server, and a session is established.
- Now the communication between caller and callee happens. The protocol used for communication may or may not be SIP. For example, instant messages can be transmitted over SIP. Voice conversations are typically transmitted over RTP.
- Now, callee finishes the conversation and wishes to terminate the session by sending a BYE request.
- Caller responds with a 200 OK status code to accept session termination.
In the above scenario, the SIP proxy server simply routes the messages to the callee's current address. As you can imagine, more interesting and smart routing services can happen. For example, the proxy server can "follow a user" by routing the messages to where he can be reached, such as a cell phone, even if someone is calling on his office phone.
Defined in Java Specification Request 116, the SIP Servlet Specification provides a container-servlet programming model for SIP applications. Since it is derived from the Java servlet architecture in Java EE, JSR 116 brings a familiar approach to building SIP services to Java EE developers.
The table below summarizes the similarity between
Comparison between an HTTP and SIP servlet
Much like HTTP servlets, SIP servlets extend the
javax.servlet.sip.SipServletclass, which in turn extends the
javax.servlet.GenericServletclass. As you might have guessed,
service(ServletRequest request, ServletResponse response)method to handle different types of SIP messages.
Since SIP is asynchronous, only one of the request and response arguments in the
service()method is valid; the other one is null. For example, if the incoming SIP message is a request, only the request is valid and the response is null, and vice versa. The default implementation of the
SipServletclass dispatches requests to
doXXX()methods and responses to
doXXXResponse()methods with a single argument. For example,
doInvite(SipServletRequest request)for a SIP invite request and
doSuccessResponse(SipServletResponse response)for SIP 2xx class responses. Typically SIP servlets override
doXXXResponse()methods to provide application logic.
How do you send SIP responses if there is no response object in the
doXXX()methods? In SIP servlets, you must call one of the
createResponse()methods in the
javax.servlet.sip.SipServletRequestclass to create a response object. Then, call the
send()method on the response object to send the response.
How about creating a SIP request in a SIP servlet? There are two ways to create SIP requests: Call either one of the
createRequest()methods on the
SipSessionclass to create a SIP request within the session, or one of the
javax.servlet.sip.SipFactoryto create a SIP request within a new
SipSession. To get an instance of
SipFactory, you must call
SipFactoryis a factory interface in the SIP Servlet API for creating various API abstractions, such as requests, address objects, and application sessions. One interesting object created by
javax.servlet.sip.SipApplicationSession. The intention of JSR 116 is to create a unified servlet container that can run both an HTTP and a SIP servlet.
SipApplicationSessionprovides a protocol-agnostic session object to store application data and correlate protocol-specific sessions, such as
HttpSession. Hopefully this concept will be adopted by future versions of the Servlet API to make it
SipApplicationSessionmanages protocol-specific sessions like
SipSessioninterface represents the point-to-point relationship between two SIP endpoints and roughly corresponds to a SIP dialog defined in Request for Comments 3261.
SipSessionis inherently more complicated than its HTTP counterpart due to SIP's asynchronous and unreliable nature mentioned above. For example, Figure 3 shows the
SipSessionstate transitions defined in JSR 116:
Figure 3. State transitions in SipSession
HttpSessionis created when a user logs in and destroyed after logout. A
SipSessiontypically represents one logical conversation, even if you have multiple conversations between the same endpoints. So
SipSessionis more dynamic and has a shorter lifespan.
More advanced discussions of the
SipSessionlifecycle and its relationship with SIP dialog reaches beyond this article's scope. Fortunately, the container handles most of the complexity, such as lifecycle and state transitions, and
SipSessioncan simply be used as storage for session data.
A complete example: EchoServlet
The EchoServlet is a SIP servlet that can echo the instant messages you type in Windows Messenger:
Figure 4 shows how the SIP message flows between Windows Messenger and EchoServlet:
Figure 4. Message flow between Windows Messenger and EchoServlet
You can compile EchoServlet just like any Java code. Just make sure servlet.jar and sipservlet.jar (part of JSR 116 distribution) are on the classpath.
Similarly to HTTP servlet applications, each SIP servlet application has a deployment descriptor: sip.xml. Here is an example:
The noticeable differences from a typical web.xml are the servlet mapping rules. Instead of specifying a URL pattern, you must write a Boolean expression in XML with various values in the SIP request headers. The SIP servlet container evaluates all the expressions from different applications for each initial SIP request—the SIP request does not belong to any existing
SipSession. If an expression is evaluated to be true, the corresponding SIP servlet is invoked. If there are multiple matches, the container may simply invoke the first matching servlet or have other local policies.
In the above sip.xml, we simply specify that EchoServlet accepts the initial SIP REGISTER and INVITE requests. Once the session is established, all the messages sent within the session, such as MESSAGE and BYE, are automatically delivered to the servlet associated with the session.
Now, you must create a SIP servlet application package with EchoServlet and sip.xml in order to deploy and run. Similar to an HTTP servlet application, a SIP servlet application must be assembled in a SIP application archive (SAR). A SAR is simply a Java Archive (JAR) with additional requirements for the directory structure and content. The structure of SAR resembles WAR and should look something like the following:
You can simply create the SAR using the
jarcommand from the top directory:
jar cv0f echo.sar.
Deploying SAR in SIPMethod
Now it is time to deploy your SAR into your favorite SIP servlet container. Since each container has different deployment mechanisms, as an example, I use SIPMethod Application Server, a SIP servlet container from Micromethod Technologies.
Assuming you have properly downloaded and installed SIPMethod Application Server, to deploy a SAR into SIPMethod Application Server, you simply copy the SAR into SIPMethod's sipapps directory:
cp echo.sar <sm_home>/sipapps
copy echo.sar <sm_home>\sipapps
<sm_home>is where you install SIPMethod Application Server.
Once SIPMethod starts, it will expand echo.sar into the echo directory under sipapps. Here is an example of the directory structure:
Figure 5. Directory structure after deployment
Test the EchoServlet
Assuming you have deployed echo.sar properly, you can start SIPMethod Application Server using its startup script:
EchoServlet requires Windows Messenger 5.0 or above. Please configure Windows Messenger with the following steps:1. Open the Options dialog from the Tools menu
2. Open the Accounts tab in the Options dialog
3. Enable SIP Communications Service Account by checking "My contacts include users of a SIP Communications Service"
4. Type a name, such as firstname.lastname@example.org, in the Sign-In Name field
Figure 6. Configure SIP account in Windows Messenger. Click on thumbnail to view full-sized image.
5. Open SIP Communications Service Connection Configuration dialog by clicking the Advanced... button
6. Click the Configure Settings radio button
7. Type IP address or machine name of where SIPMethod is running, such as 192.168.0.4, in Server Name or IP Address field
8. Select either TCP or UDP
Figure 7. Configure SIP connection in Windows Messenger. Click on thumbnail to view full-sized image.
Now make sure SIPMethod Application Server is running; sign into Windows Messenger with the sign-in account for the SIP Communications Service you entered in Options, such as email@example.com. Now you can start a Send an Instant Message window by selecting the Actions menu, then Send an Instant Message... . Please select the Other tab and type in a name, such as firstname.lastname@example.org, in the email address field. Then click OK.
Figure 8. Start a SIP chat session in Windows Messenger. Click on thumbnail to view full-sized image.