标签:
jainsip |
摘要:会话发起协议(SIP)将在3G网络中发挥重要的作用,而JAIN SIP是用Java语言实现的SIP类库。简要介绍了SIP协议的规范,详细分析了JAIN SIP的体系结构和实现机制,并用代码片断和交互图的方式描述了基于SIP协议应用的开发过程。用JAIN sIP 开发基于SIP 协议的应用不仅可以提高开发效率,而且将使应用程序获得较高的可靠性和较好的移植性。
1 SlP
SIP(Session Initiation Protocol,会话发起协议)是由IETF(Internet工程任务组)提出的IP信令协议。它的主要作用是解决IP网中的信令控制,以及同SoftSwitch的通信,从而构成下一代网络的增值业务平台,为通信、交通、金融等行业提供更好的增值业务。
1.1 SIP概述
SIP是一个与HTTP和SMTP类似的、基于文本的应用层控制信令协议,用于建立、修改或结束一个或多个参与者的会话。SIP会话中的各参与方可以通过多播或单播的方式进行通信。SIP通过代理和重定向请求到用户当前位置来支持用户的移动性。由于SIP没有捆绑于任何特定的会议控制协议,因而协议具有普遍性,可以用于开发Internet多媒体会议、Internet电话呼叫、多媒体分发、网络游戏以及虚拟现实等方面的应用。SIP对传输层和网络层没有特殊要求,除IP网络之外,还可以运行于ATM AAL5,IPX,Frame Relay或x.25上。而在IP网络中,SIP可以利用UDP或TCP作为传输层协议,一般情况下使用UDP,而传输的可靠性则由SIP来保证。与HTrP类似,SIP定义了6种基本的方法、6类状态编码和一系列的SIP消息首部用于信令的传递和控制功能的完成。SIP的方法定义不同的信令处理功能,6种方法包括INVITE。BYE,CANCEL,分别用于呼叫的请求、挂断和取消;ACK用于对请求回应的确认;OPTIONS用于会话中参数的协商和改变;REGISTER用于用户的位置信息在SIP服务器上登记。状态编码从lxx到6xx,在请求回应中指出服务器端对请求处理的结果和工作状态,如lxx指出请求在进一步处理中,需要暂时等待,2xx表示请求处理成功结束,3xx表示请求被重定向,等等。消息首部用来指明一些有关主叫/被叫、消息路径、报文体的信息,如Call—ID用于唯一标识一次会话呼叫;CSeq唯一标识一次会话中的一个请求;To指出请求的接收方;From指出请求的发起方;Contact可以包含位置信息,用于实现一些高级功能,如呼叫转移等。
1.2 SIP的主要运行过程
SIP的主要运行过程包括:注册、通过代理模式建立连接、通过重定向模式建立连接和呼叫复制。注册过程包括以下步骤:用户端启动后,通过组播包向注册服务器发送注册请求;由注册服务器决定注册超期时限;注册服务器向定向服务器发送当前的注册表;注册服务器支持代理服务以保障用户的移动性。通过代理模式建立连接包括以下步骤:代理服务器首先接收用户端发送的INVITE消息包;代理服务器通过定位服务器来确定被叫方的位置;代理服务器将INVITE消息包发送给被叫方;被叫方的应用程序响应呼叫并向代理服务器发送成功消息包,该消息包通过相同的路由发送给代理服务器;代理服务器向呼叫发起方转发呼叫成功消息;呼叫发起方接收到成功建立连接的消息,并直接向被叫方发送ACK消息包,不再通过代理服务器。通过重定向服务器建立连接时,重定向服务器并不对请求消息包做任何处理,直接将代理服务器的地址发送给呼叫发起方。呼叫复制是代理服务器将呼叫发起方的请求复制后发送给被叫方的多个终端,并选择最早应答的终端与其建立连接。一旦呼叫方和被呼叫方建立起连接,则它们之间的交互将直接进行而不需要任何第三方参与;任何一方都可以直接向对方发送BYE 消息终止会话。
2 JAIN SIP和H'ITP以及SMTP一样,SIP使用ASCII来定义,任何一个开发人员可以很容易地使用任何程序设计语言来实现这个协议,他们所要处理的都将是字符串数据。目前已经有多个SIP的实现。JAIN(Java AdvancedIntcnigcnt Network)是SUN公司开发的一系列高级智能网Java类库,其中JAIN SIP是其对SIP提供支持的类库。由于JAIN SIP API是对SIP标准 的完整定义,所以任何基于SIP的应用都可将JAIN SIP API作为Java标准接口,用到任何SIP应用实例中。这意味着应用服务器、SIP 电话、网关及网关控制器、SIP服务器、基于SIP的业务、SIP计费解决方案、开发工具包、SIP测试工具、SIP用户代理以及SIP网络管理,均可利用JAIN SIP API来提供一个高度可移植性的实现。
2.1 JAIN SIP体系结构
JA/N SIP利用Java的面向对象特性,用对象、消息以及事件来描述SIP协议。在JAIN SIP体系结构中,为所有SIP报头和报文定义了类,并借助提供者/监听者(SipProvidcr!SipListcncr)接口,将用于处理报文的JavaBcans体系结构的接口定义为事件。一个典型的JAIN SIP应用程序如图1所示。应用程序 应用程序
图1 JAIN SIP应用程序结构
Stack直接对应于实现SIP协议栈的数据结构,所有的SIP消息和状态码都由Stack通过网络收发。它不提供面向对象功能,可以说是SIP 的一个原始实现。SipProvider是一个接口,通过Listening Point封装了对Stack进行操作的方法,将SIP 以面向对象的形式提供给上层对象。SipProvider不关心一个SIP消息在应用程序中的意义,它的职责仅仅是通过上、下层的接口处理SIP消息的准确发送和接收。在逻辑上,两个SIP应用程序之间的交互就表现为它们之间的SipProvidcr进行交互。SIP协议本质上是一个请求/应答协议,是一个无状态的协议,这样的目的是为了简化各代理服务器的功能,提高其处理用户请求的能力,同时也增强了SIP应用程序的灵活性;但另一方面,无状态的协议又不能很好地直接支持事务的概念。为了给上层应用提供一个易用的事务支持,SipProvider提供了客户端事务(Client Transaction)和服务器端事务(Server Transaction)的创建方法,它提供了对有状态的请求/应答消息的良好支持。SipProvider同时支持无状态的请求/应答消息,这是SIP的默认消息类型。一个应用程序中可以有多个SipProvidcr,每个对应一个Stack。应用程序通过一个SipListener管理一个或多个SipProvider。SipProvider的行为依赖于应用程序的业务逻辑。当一个SipProvider建立之后,将被注册到一个SipListener;应用程序如果需要访问某个SipProvider,就通过SipListcncr向该SipProvider发送消息;如果SipProvidcr收到了其他SipProvidcr的sIP消息,需要将其传递给应用程序进行解析,此时它将产牛一个事件,sipListencr理解事件的含义并能根据不同的事件触发相应的响应。
2.2 JAIN SIP 对象初始化过程从JAIN SIP应用程序的结构我们可以看出,JAIN SIP的开发都是围绕着SipListener和SipProvidcr进行的。实际上,还有其他对象参与共同实现其功能,在程序的开始阶段必须进行初始化,以创建一系列必须的对象。图2描述了一个JAIN SIP应用程序中各个对象的创建关系。图2 JAIN SIP对象体系结构对象的创建过程为:
1)JAIN SIP应用程序调用ctcatcListener方法创建出一个全局唯一的SipListener对象:
2)SipListener通过getlnstance方法创建SipFactory对象,并通过其创建SipStack对象;
3)SipStack对象创建SipProvidcr,并将其私有的SIP
Stack交由SipProvider管理;
4)一旦一个SipProvidcr成功建立,SipListcncr就对其进行注册,建立起消息/事件机制,从而完成初始化。SipStack对象负责维护SIP Stack,因而创建的时候有一
些重要的属性需要设置,其代码片断如下:
Properties properties =new Properties();
Properties.setProperty(”jav~x.sip.IP_ADDRESS”,
”211.69.194.123”);
Properties.setProperty(”java.sip.OUTBOUND—PROXY“,
”202.1 14.0.243:5070/UDP“);
. . . // other initialization prope rties
sipStack=sipFactory.createSipStack(properties);
2.3 JAIN SIP呼叫请求的发送与处理当各对象初始化完成之后就可以通过请求和响应消息的方式和其他的JAIN SIP对象进行通信了,JAIN SIP提供给程序员完全面向对象的方式来处理这种请求和响应。以下用几个代码片断来说明。
1)创建请求消息,将SIP Request消息以正确的参数填充,包括请求类型、请求编号等:
SipURI rcquestURI = addressFactory.createSipURI(toUser,toSipAddress);
,,create other headersRequest request = messagcFactory.createRequest
(requestURI,Request.INVITE,eaUldHeader,eSeqHeader,fromHeader,toHeader,viaHeaders,maxForwards);
2)SipProvider创建ClicntTransaction对象,将刚刚填充的request发送出去:
ClientTransaction inviteTid =SipProvider.getNewClientTransaction(request);InviteTid.sendRequest();
3)将收到的SIP Request作为事件,交由ServcrTransaction
处理:public void processRequest(RequestEvent requestEvent)lRequest request=requestEvent.getRequest();ServerTmnsaction st=requestEvent.getServerTransaction();
. . .
//do request specific processing here
l
3 JAIN SIP开发的一个实例使用JAIN SIP既可以开发用户代理端实例(包括UAC
UAS),也可以方便地开发各种SIP服务器,本节以一个无状态的SIP代理服务器为例说明。该服务器维护一个本地用户的列表,为本地用户转发呼叫,并记录其当前位置。当服务器收到一个对本地用户的呼叫时,它将查询数据库得到呼叫目标的当前位置,并将呼叫转发到相应位置。对于外来漫游到本地的用户,该服务器将把对其的呼叫转发到其归属服务器。图3解释了无状态SIP服务器接收本地用户的注册并转发呼叫的过程。
图4 无状态SIP代理服务器注册过程使用JAIN SIP对象和方法,可以很容易地对上述过程提供支持,我们仅以注册(Register)过程为例。图4是JAIN SIP开发的无状态SIP服务器接收用户的注册过程交互图。
代理服务器处理用户代理的注册过程为:
1)SipStack接收到用户代理发送的REGISTER请求;
2)SipProvider获取SipStack中的请求消息字符串,并交由SipParser格式化为标准请求消息;
3)SipProvider向SipListener通报用户注册事件;
4)SipListener被事件触发,在用户数据库中校验用户的权限,确认后如需更新则更新数据库;
5)验证成功后SipListener返回状态码给SipProvider,SipProvider将其转发给SipStack,最后发回给用户代理。
本文所述的SIP代理服务器注册过程的实例是一个较有代表性的例子,如果采用直接解析SIP消息的方法将使开发过程纠缠于大量的文本解析与处理上,使用JAIN SIP则将其转化为对消息和事件的处理,提高了开发的效率。由于Java语言提供的垃圾收集以及平台无关特性,使用JAIN SIP同时也使应用程序获得较高的可靠性和移植性。
图4 无状态SIP代理服务器注册过程使用JAIN SIP对象和方法,可以很容易地对上述过程提供支持,我们仅以注册(Register)过程为例。图4是JAIN SIP开发的无状态SIP服务器接收用户的注册过程交互图。
代理服务器处理用户代理的注册过程为:
1)SipStack接收到用户代理发送的REGISTER请求;
2)SipProvider获取SipStack中的请求消息字符串,并交由SipParser格式化为标准请求消息;
3)SipProvider向SipListener通报用户注册事件;
4)SipListener被事件触发,在用户数据库中校验用户的权限,确认后如需更新则更新数据库;
5)验证成功后SipListener返回状态码给SipProvider,SipProvider将其转发给SipStack,最后发回给用户代理。
本文所述的SIP代理服务器注册过程的实例是一个较有代表性的例子,如果采用直接解析SIP消息的方法将使开发过程纠缠于大量的文本解析与处理上,使用JAIN SIP则将其转化为对消息和事件的处理,提高了开发的效率。由于Java语言提供的垃圾收集以及平台无关特性,使用JAIN SIP同时也使应用程序获得较高的可靠性和移植性。
后一篇:利用Java实现 SIP的建立