Introduction to SIP, Part 1: SIP SERVLET

Source: Internet
Author: User

Summary
Session Initiation Protocol (SIP) is an important signaling Protocol that is rapidly adopted by the telecom industry to build next-generation applications. Java is an excellent platform for SIP development, especially during server development. Similar to HTTP servlet, the SIP Servlet API makes it easier to develop the SIP service. This article introduces the SIP servlet technology and provides an example with annotations.

Introduction
Instant messaging is changing people's lives. It is a very useful tool that combines the advantages of email, Internet phone, and file transfer applications. Users can even see who is online and who is in the "busy" status ". Of course, people can use it to chat for a long time without any benefits. However, an employee can also use it to send extremely important information to the employee when the boss meets the customer.

Therefore, it is strange to see so many different types of instant messaging applications on the market. It should be a good thing to have so many choices, but what if the applications used by employees are different from those used by the boss? This will be a big problem because most of these applications use proprietary protocols.

SIP brings us the gospel. SIP is likely to become a standard instant messaging protocol.

In this article, I will develop a simple SIP application-a chat room server that allows the SIP instant messenger messaging application to communicate with each other and send messages to each other.

SIP SIMPLE
SIMPLE, short for SIP Instant Messaging and Presence Leveraging ExtensionSIP Instant Messaging and on-site support extension), is a working group and a group of SIP extensions. One of the extensions is MESSAGE messages. It can be used to send instant messages containing any combination of text and binary content. This message is very simple to use, which is why I decided to use it to develop the first SIP application.

TextClient
To test our application, I provide a small SIP instant messenger application, see the "Download" section at the end of the article ). This application sends a MESSAGE to another messenger or server. The User Interface contains the client address, the input field of the friend address, a text message, and a submit button. Figure 1 shows the running TextClient.

Figure 1. Running TextClient

To start TextClient, run the following command:

Java-jar textclient. jar dev2dev. textclient. TextClient username port
This command uses the jain sip api reference implementation as a SIP protocol stack. We provide the source code of this tool. If you want to learn more, I recommend that you read the source code.

ChatRoomServer
The following are the requirements of the sample application.

A chat room is a virtual space in which different instant messenger applications can interact. Messages sent to the chat room will be broadcast to all others in the chat room. In other words, all messages can be viewed by all users. This means that when a message arrives at the server application, the user's address will be added to a list. The message is then sent to all users in the list.

In addition, "commands" can be implemented ". The command starts with a forward slash (/). It is not broadcast, but processed by the server itself for specific functions. The commands I implemented include:

/Join: enter a chat room without broadcasting any messages.
/Who: print a list of all users in the chat room.
/Quit: No messages are sent in when you leave the chat room.
SIP Servlet API
The SIP Servlet API (JSR 116) is a server interface that describes a container of a SIP component or service. This is suitable for developing ChatRoomServer. Download the rule and decompress it. The generated folders include some libraries (servlet. jar, sipservlet. jar) and documents. I cannot get the reference implementation for running the sample SIP servlet, so I don't think you have to bother looking for it.

The core concept of the SIP servlet is to include. The SIP service is a packaged SIP servlet deployed or running on a container or SIP application server. Containers provide many services that can be used by the application, such as automatic retry, message scheduling and queuing, shunting and merging, and status management. Applications only need to contain advanced message processing and business logic. This makes the development of the SIP service a breeze.

The purpose of this article is not to provide a comprehensive introduction to the SIP Servlet API technology. Therefore, I only briefly outline the API and sample code. For more information, see the reference section at the end of the article.

Server code
If you have developed an HTTP servlet, you will be very familiar with the server code. If you do not know what servlet is, you should first understand. The SIP Servlet specification is an extension of the HTTP Servlet specification. Its syntax, container behavior, and even method names are similar.

I will analyze the example in detail below. It consists of three parts:

Lifecycle Method
These methods are called by the container when the servlet is started or closed:

public class ChatRoomServer extends SipServlet {/** Context attribute key to store user list. */public static String THE_LIST="dev2dev.chatroomserver.userList";/** Init parameter key to retrieve the chat room's address. */public static String THE_NAME="dev2dev.chatroomserver.name";/** This chat room server's address, retrieved from the init params. */public String serverAddress;/** This is called by the container when starting up the service. */public void init() throws ServletException { super.init(); getServletContext().setAttribute(THE_LIST,new ArrayList()); serverAddress = getServletConfig().getInitParameter(THE_NAME);}/** This is called by the container when shutting down the service. */public void destroy() { try {  sendToAll(serverAddress, "Server is shutting down -- goodbye!"); } catch (Throwable e) { //ignore all errors when shutting down.  e.printStackTrace(); } super.destroy();}...

In the initialization method, I created a global attribute shared by all sessions. This is the user list. I also got the address servlet parameter of the chat room) for future use.

  • Message Processing Method

    The SIP servlet is slightly different from the HTTP servlet. For HTTP Servlets, You can process incoming requests and send response messages. The SIP servlet can send and receive requests and responses. I will explain how to do this.

    When receiving a message request or response), the container will call the following method. The container will call these methods in the order shown below, or rewrite these methods to process messages based on the Message Type:

    Void service (ServletRequest, ServletResponse) If you rewrite it, do not forget to call super. service (). By default, it calls one of the following methods:
    Void doRequest (SipServletRequest)
    If you rewrite it, do not forget to call super. doRequest ().
    By default, it calls one of the following methods:
    Void doResponse (SipServletResponse)
    If you rewrite it, do not forget to call super. doResponse ().
    By default, it calls one of the following methods ::
    One of the following request methods is self-explanatory ):
    • DoAck (SipServletRequest)
    • DoBye (SipServletRequest)
    • DoCancel (SipServletRequest)
    • DoInfo (SipServletRequest)
    • DoInvite (SipServletRequest)
    • DoMessage (SipServletRequest)
    • Donoquest (SipServletRequest)
    • DoOptions (SipServletRequest)
    • DoPrack (SipServletRequest)
    • DoRegister (SipServletRequest)
    • DoRequest (SipServletRequest)
    • DoResponse (SipServletResponse)
    • DoSubscribe (SipServletRequest)
    One of the following response methods:

    • DoProvisionalResponse (SipServletResponse)-corresponds to 1xx-class Response Message.
    • DoSuccessResponse (SipServletResponse)-corresponds to 2xx-class Response Message.
    • DoRedirectResponse (SipServletResponse)-corresponds to 3xx-class Response Message.
    • DoErrorResponse (SipServletResponse)-corresponds to 4xx-, 5xx-, and 6xx-class response messages.
  • For example, MESSAGE can call the following method:

    1. Service (), input a SipServletRequest must undergo type conversion) and null
    2. DoRequest ()
    3. DoMessage ()

    Generally, only the last-level method is overwritten unless a non-standard SIP message is used or statistics about the message is collected.
    The following code processes instant messages:

    /** This is called by the container when a MESSAGE message arrives. */protected void doMessage(SipServletRequest request) throws        ServletException, IOException {    request.createResponse(SipServletResponse.SC_OK).send();    String message = request.getContent().toString();    String from = request.getFrom().toString();    //A user asked to quit.    if(message.equalsIgnoreCase("/quit")) {        sendToUser(from, "Bye");        removeUser(from);        return;    }    //Add user to the list    if(!containsUser(from)) {        sendToUser(from, "Welcome to chatroom " + serverAddress +                ". Type '/quit' to exit.");        addUser(from);    }    //If the user is joining the chat room silently, no message    //to broadcast, return.    if(message.equalsIgnoreCase("/join")) {        return;    }    //We could implement more IRC commands here,    //see http://www.mirc.com/cmds.html    sendToAll(from, message);}/** * This is called by the container when an error is received * regarding a sent message, including timeouts. */protected void doErrorResponse(SipServletResponse response)        throws ServletException, IOException {    super.doErrorResponse(response);    //The receiver of the message probably dropped off. Remove    //the receiver from the list.    String receiver = response.getTo().toString();    removeUser(receiver);}/** * This is called by the container when a 2xx-OK message is * received regarding a sent message. */protected void doSuccessResponse(SipServletResponse response)        throws ServletException, IOException {    super.doSuccessResponse(response);    //We created the app session, we have to destroy it too.    response.getApplicationSession().invalidate();}

    The first method is called when a MESSAGE is received. Initially, a 200 OK message was returned, indicating that the message was received. Then it processes server commands, such as/join. Finally, it calls a business logic method to broadcast incoming messages.

    The incoming error response message indicates that the previous request failed. This may mean that a user is disconnected. You only need to remove the user from the list.

    A successful response MESSAGE indicates that the previous MESSAGE was correctly received by instant messenger. Therefore, the session is no longer needed and can be deleted. Generally, a MESSAGE is sent in stateless form and does not store the connection information between messages. This is not the case for INVITE messages. It opens a stateful session and sends BYE messages .)

  • Business Logic code

    The remaining code consists of the helper method. The first two methods send messages to instant messenger. To send a message, use a factory to create the following two items:

    • A SipApplicationSession will be detailed later)
    • One Request Message

    In this case, you can modify the message as you like. In our example, we add instant message text to the Server Load balancer. Finally, send the message.

    private void sendToAll(String from, String message)        throws ServletParseException, IOException {    SipFactory factory = (SipFactory)getServletContext().        getAttribute("javax.servlet.sip.SipFactory");    List list = (List)getServletContext().getAttribute(THE_LIST);    Iterator users = list.iterator();    while (users.hasNext()) { //Send this message to all on the list.        String user = (String) users.next();        SipApplicationSession session =            factory.createApplicationSession();        SipServletRequest request = factory.createRequest(session,                "MESSAGE", serverAddress, user);        String msg = from + " sent message: \n" + message;        request.setContent(msg.getBytes(), "text/plain");        request.send();    }}private void sendToUser(String to, String message)        throws ServletParseException, IOException {    SipFactory factory = (SipFactory)getServletContext().        getAttribute("javax.servlet.sip.SipFactory");    SipApplicationSession session = factory.createApplicationSession();    SipServletRequest request = factory.createRequest(session,            "MESSAGE", serverAddress, to);    request.setContent(message.getBytes(), "text/plain");    request.send();}private boolean containsUser(String from) {    List list = (List)getServletContext().getAttribute(THE_LIST);    return list.contains(from);}private void addUser(String from) {    List list = (List)getServletContext().getAttribute(THE_LIST);    list.add(from);}private void removeUser(String from) {    List list = (List)getServletContext().getAttribute(THE_LIST);    list.remove(from);}}
    1. Deployment descriptor

      For HTTP Servlets, you must also write the web. xml deployment descriptor. In the SIP servlet, the corresponding file is sip. xml, in which we list the SIP servlet, initialization parameters, And the ing of which SIP servlet processes the SIP messages ). For more information about the File Syntax, see the DTD in section 15.5 of the SIP Servlet specification. Its syntax is similar to web. xml, Label. It does not map a URL pattern to servlet, but describes a condition based on the content of the field and sub-field. a sip request must meet this condition before it can be mapped to servlet. Section 11th of the SIP Servlet specification describes all fields, child fields, and conditions for this ing.

      Note that this ing is only used for initial requests. Subsequent requests in the same session/dialog are processed by the same servlet that processes the initial request.
      The following is the XML code for ChatRoomServer:

       
          
              
         
          ChatRoomServer
               
         
          dev2dev.chatroomserver.ChatRoomServer
               
                  
          
           dev2dev.chatroomserver.name
                   
                   
          
           sip:chatroomname@serveraddress
                
            
           
              
         
          ChatRoomServer
               
                              
                         
           request.uri.user               
                          
           
            chatroomname
                       
                     
                       
           request.method             
           
            MESSAGE
                      
                         
            
        
       

      The code looks very complex, but not so. Servlet ing description:

      If the user name of the request URI is the same as the chatroomname, the incoming MESSAGE request is mapped to the ChatRoomServer Servlet.

      The chat room name is just a placeholder. During compilation, the keyword "chatroomname" is replaced with the actual chat room name ".

      What is the purpose of this operation? You can deploy the same service multiple times, each time using its unique chat room name, and the message can be automatically sent to the corresponding servlet.

      Build, package, and deploy

      You need to compile the SIP servlet and package it into the SAR (Servlet ARchives) file. These files are functionally equivalent to WAR files with the same structure. See Figure 2:

       
      Figure 2. SAR file structure

      The last step is deployment, which varies with the SIP application server. You usually need to copy the SAR file to a deployment folder and then deploy the application.

      The following Ant script can help the deployment:

           
            
            
            
            
            
            
            
            
            
                
             
            
                
                 
                 
                 
                 
                     
                  
                 
                 
                 
                 
                     
                  
                 
             
        
       
      Result

      After the chat room application is running, try to access it by running two TextClient instances. Make sure that the SIP application running on the same machine uses different ports. The following example shows three applications running on the same machine:

      • The SIP application server that runs on ChatRoomServer. The address is sip: just4fun@10.0.2.69: 5060.
      • The address is the Text client of sip: snoopy71@10.0.2.69: 5061.
      • The address is the Text client of sip: maria119@10.0.2.69: 5062.

      Figure 3 shows the result.

       
      Figure 3. Interaction between TextClient and ChatRoomServer

      Complex applications
      I know the examples in this article are a little too simple compared to the applications we usually build. In reality, most SIP applications are composed of a lot of code.

      Session and status: Generally, a SIP application is a state machine, in which the call or session remains stateful for a long time until it is disconnected. For a SIP servlet, a call is represented by SipApplicationSession, which can carry an attribute State ). In a call, the branches of each session call are represented by SipSession in the SipApplicationSession. A two-person back-to-back session uses a SipApplicationSession and two sipsessions. A meeting call may contain more sipsessions. These attributes can be included. The container automatically provides the corresponding session object according to the Message context.

      Hierarchical Design: put all the code into a single large SIP servlet. Complex applications should be designed based on relatively independent layers. An obvious layer is the database layer of the connection pool. It can also contain a business logic layer separated from the SIP signaling. Another aspect is load analysis, which should be built into a reusable layer.

      Other technologies: There are many advanced SIP servlet technologies, including request proxy, redirection and loop, Session Timeout management, authentication, internationalization, TCP support, timer, session listener, and error management. Obviously, this article does not cover all these aspects, but you can find relevant content in the SIP Servlet specification.

      Example: For more information, see references.

      Conclusion
      The standard promotes interoperability and collaboration. Collaboration-whether it is for easy chat between friends or for important file transfers-is a good thing.

      SIP is a promising telecommunications standard, and the SIP Servlet API is an excellent way to easily and quickly develop server-side SIP applications. In this article, we use a simple example to outline the SIP servlet programming. We hope that this article will help you take a big step in collaboration.

      Related Articles]

      • Introduction to SIP, Part 1: A Preliminary Study of SIP
      • Voice and IP communication: Support for the SIP protocol in Cisco Unified Communication
      • Migrate to the next generation network with SOA and SIP

      Contact Us

      The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

      If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

      A Free Trial That Lets You Build Big!

      Start building with 50+ products and up to 12 months usage for Elastic Compute Service

      • Sales Support

        1 on 1 presale consultation

      • After-Sales Support

        24/7 Technical Support 6 Free Tickets per Quarter Faster Response

      • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.