Use sipsession or sipapplicationsession in sipservlet to handle UA status changes

Source: Internet
Author: User

Let's talk about something unrelated to this Article. Today we finally use X-Lite for registration. It turns out that we need to set the proxy server that goes through the outbound call to "127.0.0.1: 5081". Of course, this is the local machine, for other computers, set the IP address to the server. 5081 is the port used by the P-CSCF in SDS, if only use IP address, it is not possible!

 

If it is a b2bua, you only need a global container hashmap <sipsession, sipsession> map to save all "surviving" sessions, but now I am a proxy Servlet and a b2bua servlet, in this way, the container in the Saved state must be shared by two Servlet classes. therefore, create the servletcontext object in the two servlets respectively, and initialize CTX = config In the init function respectively. getservletcontext (). as follows:

Public void Init (servletconfig config) throws servletexception {<br/> super. init (config); <br/> CTX = config. getservletcontext (); <br/>... <br/>} 

Then in the first servlet -- proxyservlet

Public class proxyservlet extends sipservlet {<br/>... <br/> servletcontext CTX = NULL; <br/> hashmap <sipsession, sipsession> map = new hashmap <sipsession, sipsession>; <br/>... <br/> Public void Init (servletconfig config) throws servletexception {<br/> super. init (config); <br/> CTX = config. getservletcontext (); <br/> CTX. setattribute ("statemap", MAP); <br/>... <br/>}< br/>... <br/>}

 

In the second servlet -- b2buaservlet

Public class b2buaservlet extends sipservlet {<br/>... <br/> servletcontext CTX = NULL; <br/> hashmap <sipsession, sipsession> map = new hashmap <sipsession, sipsession>; <br/>... <br/> Public void Init (servletconfig config) throws servletexception {<br/> super. init (config); <br/> CTX = config. getservletcontext (); <br/> map = (hashmap <sipsession, sipsession>) CTX. getattribute ("statemap"); <br/>... <br/>}< br/>... <br/>}

 

This solves the problem of using the same map to save the session in two servlets. But is it appropriate to use the hashmap <sipsession, sipsession> data structure? For proxyservlet, he can only get one sipsession -- request. getsession (). It may be more suitable to use list...

 

 

Public class proxyservlet extends sipservlet {<br/>... <br/> servletcontext CTX = NULL; <br/> List <sipsession> SSL = new secure list <sipsession> (); <br/>... <br/> Public void Init (servletconfig config) throws servletexception {<br/> super. init (config); <br/> CTX = config. getservletcontext (); <br/> CTX. setattribute ("statelist", SSL); <br/>... <br/>}< br/>... <br/>}< br/> public class b2buaservlet extends sipservlet {<br/>... <br/> servletcontext CTX = NULL; <br/> List <sipsession> SSL = new secure list <sipsession> (); <br/>... <br/> Public void Init (servletconfig config) throws servletexception {<br/> super. init (config); <br/> CTX = config. getservletcontext (); <br/> SSL = (list <sipsession) CTX. getattribute ("statelist"); <br/>... <br/>}< br/>... <br/>} 

 

However, there is another problem, that is, a large amount of code will appear during the search or deletion, which affects the readability of the Code. Therefore, the list <sipsession> operation is encapsulated in a statelist class.

Public class statelist {<br/> List <sipsession> SSL = new external list <sipsession> (); <br/> // integrates set and Add, no need to know the index value <br/> Public bool add (sipsession SS) {<br/> int Index = SSL. indexof (SS); <br/> If (index! =-1) <br/>{< br/> SSL. set (index, SS); <br/> return true; <br/>}< br/> else <br/>{< br/> SSL. add (SSL. size (), SS); <br/> return true; <br/>}</P> <p> // recursive call, no need to know the index value <br/> Public bool remove (sipsession SS) {<br/> int Index = SSL. indexof (SS); <br/> If (index! =-1) <br/>{< br/> SSL. remove (INDEX); <br/> This. remove (SS); <br/>}< br/> else <br/>{< br/> return true; <br/>}</P> <p> // traverse the list, returns the first sipsession with the specified STR attribute 1 <br/> Public sipsession get (string Str) {<br/> iterator <sipsession> it = SSL. iterator (); <br/> while (it. hasnext () <br/>{< br/> If (it. next (). getattribute (STR) = 1) <br/>{< br/> return it. next (); <br/>}< br/> return NULL; <br/>}< br/>}; </P> <p> 

 

Think of a problem... If sipsession is used to save the state, do list or map really need it ?... It seems that no longer needed!

Sipsession lifecycle <br/> generally, the lifecycle of a sipsession can be controlled by the following method: <br/> 1. if the parent sipapplicationsession times out or explicitly expires, the sub-sessions of all Protocols will also become invalid. <br/> 2. the application uses the invalidate () API of the sipsession to invalidate the statement. <br/> 3. the application indicates that the sipsession is invalid and the container then invalidates the session when it enters the ready-to-invalidate state. <br/> any attempt to obtain or store data on an invalid sipsession will cause the container to throw an illegalstateexception. <br/> when a sipsession is terminated, whether the parent application session times out or the session is explicitly invalid, the window must clear all sessions in this state from the memory. in this case, if you receive a subsequent request or response from the local Session, the container will process the message as follows: <br/> 1. reject this request by sending a 481 Error Response <br/> 2. routing this request or response <br/> is likely to have different lifecycles for different application instances in the same application path. the container processes subsequent requests and responses for a conversation... 

 

Haha !~ It's all nonsense! You only need to set the session attribute value (held) when you receive the 182 message as a tag. When you receive the ACK message, you can judge the Ack. getsession (). whether getattribut ("flag") equals held. if yes, proxy the ACK request and

Sipapplicationsession SAS = ack. getapplicationsession (true );

SAS. setattribute ("invite_send", "invite_send );

Sipservletrequest newreq = SF. createrequest (SAS, "invite", Ack. getto (), Ack. getfrom ());

 

Add a judgment when you receive the 200 OK message.

Resp. getmethod () = "invite" & resp. getrequest (). isinitial! = True

If "yes"

Copy the SDP information of this response

Resp. setcontenttype ("text/plain ");

String content = resp. getcontent ();

Then

Sipapplicationsession SAS = resp. getapplicationsession (true );

Judge SAS. getattribute ("invite_send") = "invite_send ";

If yes

Sipservletrequest newreq = SF. createrequest (SAS, "invite", resp. getfrom (), resp. getto ());

Newreq. setcontenttype ("text/plain ");

Newreq. setcontent (content, "text/plain ");

Newreq. setcontenttype ("SDP/application ");

Newreq. setcontentlength (content. Length ());

Newreq. Send ();

SAS. removeattribute ("invite_send ");

Resp. createack (). Send ();

 

Of course, these are all functions completed in proxyservlet. Tomorrow, we will write the functions to be completed by the methods in b2buaservlet.

 

 

 

Related Article

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.