标签:
javasip |
会话初始化协议(Session Initiation Protocol,SIP)最近几年受到了极大的关注,将SIP作为第三代移动通信的信令协议提供IP多媒体服务的决定,使得SIP成为又一个技术热点。SIP将蜂窝系统与Internet应用领域融合在一起,使用户能够把传统的Internet服务,比如E—mail、Web以及多媒体和即时消息等新服务结合起来。
l SIP介绍
会话发起协议(Session Initiation Protocol,SIP)是由IETF提出的IP电话信令协议,用于生成、修改和终结一个或多个参与者之间的会话,在IP网上实现端到端的通信。SIP协议源于H1TP协议(超文本传输协议),其会话采用点对点的resquest/reponse模式,并且针对移动性有专门的设计。
SIP提供以下两个基本功能:
1)会话的建立、调整和终止
SIP用于发起会话,控制多用户参加的多媒体会话的建立和终结,并能动态调整和修改会话属性,如会话带宽要求、传输媒体类型(语音、视频和数据等)、媒体编解码格式、对组播和单播的支持等。
2)用户可移动性
在一个SIP环境中,用户使用SIP统一资源定位器(URL)标识自己。SIP URL的格式和一个E—mail地址相似,
通过用户名或主机名等元素来构造,通常由一个SIP标识、一个用户名和一个域名组(如:SIPuser@company.com)。
如果一个用户想被他人找到,则必须向SIP服务器登记他当前的位置。SIP主叫方根据被叫方的公开地址,通过SIP重定向/代理服务器查询被叫方当前地址,实现对用户定位,建立会话。SIP协议定义了多个实体,分为用户代理和服务器两种。用户代理是呼叫的终端级元素,服务器是处理与多个呼叫相关联信令的网络设备。用户代理UA(User Agent)是提供用户交互功能的SIP终端实体。用户代理本身又分为用户代理客户端UAC(User Agent Client)和用户代理服务器UAS(User Agent Server)。UAC发起呼叫,UAS应答呼叫,使点到点的呼叫能够通过客户机/服务器模式完成。服务器按照功能的不同分为重定向服务器、代理服务器.和注册服务器。重定向服务器通过提供可以选择的位置信息帮助定位SIP用户代理,这些位置可能是连通用户的地点。重定向服务器接受经代理服务器转发的用户代理呼叫请求,向代理服务器返回被呼叫用户可能出现的位置列表,并由用户代理直接连接的代理服务器进行用户定位的所有尝试。代理服务器在会话建立或修订过程中主要起消息的中继转发作用,并且在会话建立时代替呼叫者的用户代理去尝试连接被呼叫用户可能出现的地址,确定被呼叫者的位置。注册服务器是接受注册的SIP服务器,接受本域用户的注册请求,完成用户地址的注册。这些服务器按逻辑功能的不同进行分类,在实际应用中,可以根据具体情况将若干逻辑实体合并在一个物理实体中,比如某些情况下用户数不多的时候,可以把重定向服务器、代理服务器和注册服务器放在一个物理服务器上实现,并将该服务器称为SIP服务器。
2 SIP实现机制
IETF提出的SIP协议规定了SIP系统实现的基本实体、体系结构、工作原理、编码格式、消息结构等,但是对SIP呼叫控制系统的实现没有提出一个完整的模型。2001年1月SUN公司向广大开发者发布了JAIN SIP API—— 一个基于Java技术的规范,该规范定义了SIP通信实体的模块、接口、工作架构以及流程等。JAIN SIP把SIP协议规范为标准的Java接口,它标准化了协议栈接口、消息接口、事件和事件语意,同时也规定了检测利用其所开发应用的可移植性的方法。用这些接口可实现SIP通信中的用户代理和所有服务器。JAIN SIP对SIP通信实体的实现采用模块化处理,每个实体都由SipListener、SipProvider和SipStack构成。SipListener通常包含在一个应用中,代替应用向SipProvider请求SIP服务。每个SIP实体均是扩展SipListener而来,通过在扩展的基础上增加不同的逻辑操作,实现用户代理、代理服务器、注册服务器和重定向服务器等不同的应用。SipProvider是SIP协议栈向应用提供服务的接口,应用调用的SIP服务都由SipProvider提供。SipStack是SIP协议栈,是整个JAIN SIP的核心实现部分,所有操作都在这里实现,包括产生地址、消息编解码、消息事件的生成、会话的建立、传输的建立、以及地址的解析等等。SipStack是SipListener和SipProvider的基础,其实现的SIP服务由SipProvider统一向SipListener提供。这三部分关系如图1所示。
从图中可以看到应用必然包含SipListener或者是由SipListener扩展而来,并且由SipListener向SipProvider申请SIP服务。SipProvider作为SIP服务提供接口向SipListener提供包括建立对话、产生事务、产生消息体、编解码等全套SIP服务,而这些服务具体由SipStack执行。这三个对象的实现也要有规定的顺序。首先通过具体构造函数构建SipListener,由SipListener产生一个SIP工厂(SIPFactory),并由SIP工厂实例化SipStack,然后SipStack产生SipPmvider,并使SipListener与SipProvider建立关联。至此,JAIN SIP各个对象均已建立并产生关联。同样从图I中可以看出,应用中的SipListener产生消息发送至SipProvider,SipProvider通过与协议栈的监听点绑定来同SIPStack建立关联,SIPStack执行对消息的操作,并且通过网络发送至接收方的SIPStack。接收方接收到的被称为SIP事件,SipProvider原封不动的将SIP事件提交给SipListener并由SipListener根据事件类型进行具体操作。
3 SIP通信模型
模拟SIP通信的模型具备在局域网内实现点对点呼叫、利用用户名呼叫和跨域呼叫等功能。为了实现这些功能,本模型由用户代理、代理服务器、注册服务器、定位服务器和个性化服务器组成。其中除个性化服务器,其余服务器均与SIP规范中定义的SIP实体相对应,个性化服务器用来保存域内用户信息和个人设置,如保存用户名和用户SIP号的对应关系,使用户只用输入用户名就可以登录,并且可以保存每个用户的地址簿。
3.1 模型结构
图2中展示了跨域连接的模型体系结构图。每个域至少有一套代理服务器、注册服务器、定位服务器和个性化服务器。用户通过用户代理登录时,用户代理首先向直接连接的代理服务器发送登录请求,该代理服务器从与它直接连接的注册服务器中查询该用户是否为在本域注册的用户,若是则将该用户当前地址保存到定位服务器并完成登录;若不是则将该登录请求发送至该用户所属域的代理服务器(在实际情况中是该用户购买服务的网络运营商经营的域中的代理服务器),并且将用户当前地址信息存人对应的定位服务器完成用户登录。
当用户A向用户 发起呼叫时,用户A将呼叫请求发送至它直接连接的代理服务器,由此代理服务器将请求转发至用户B原始域(实际情况中用户购买SIP服务的网络运营商经营的域)的代理服务器,再从该域对应的定位服务器查到用户曰当前地址信息,并且将呼叫请求转发至该地址,用户口对该呼叫请求进行响应,决定是否建立连接。
3.2 模型实现
整个模型用Java语言编码,除了个性化服务器之外,其他通信实体均根据JAIN SIP架构构建,通过扩展SipListener
而来,在扩展时添加不同的逻辑操作实现各个实体不同的功能。本文重点以代理服务器为例重点介绍,其他服务器在利用JMN SIP方面大同小异。代理服务器是整个系统的核心部分,在整个模型中起重要作用。主要功能为处理接收到的SIP请求,向注册服务器转发注册请求;查询定位服务器,获取用户的sipUrl地址,根据SIP请求向被呼叫方的sipUrl进行转发。代理服务器的功能由以下几个模块来完成:
1)主模块。读取参数初始化代理服务器,启动线程来查询定位服务器中的数据信息并将结果存储,开启SIP监听,处理SIP的注册、呼叫请求、响应及超时处理。
2)查询结点信息模块。用来存放SIP请求信息,存放于查询队列中。
3)查询队列模块。用来存放需要进行处理的查询结点信息,分为查询输入队列incomingQueue和查询输出队列
outgoingQueueo
4)查询处理模块。开启线程从查询队列中取出查询结点信息,解析数据后向定位服务器进行查询,并将结果存储回查询队列中。代理服务器共启动了两个线程,分别为Proxy主线程和解决地址对应的Requestu Resolver线程。服务启动后,首先初始化Proxy服务器,包括产生SipFactory、SipStack和SipProvider,并且设置他们的属性,然后启动Proxy线程,即启动消息监听,然后再启动RequestudResolver线程。代理服务器建立SIP通信的流程如图3所示。
代理服务器是对SipListener的扩展,并且在主线程Proxy中先得到SipFactory的实例,由此实例生成SipStack。在设置SipStack的各个属性值后,产生SipProvider,将SipListener与SipProvider建立关联。这部分代码如下:
//得到SipFactory的实例
sf= SipFactory.getlnstance();
sf.setPathName(”net.siptrex”);
//由SipFactory生成SipStack
try(
SS= sf.createSipStack();
)
catch(SipPeerUnavailableExcept
1ogfttError”.”Siptrex JAIN SIP stack could not be loaded:” +
X.getMessage());
System.exit(一1);
)
catch(SipException x)f
log(t.Error”,”Siptrex JAIN SIP stack could not be loaded:” +
X.getMessage());
System.exit(一1);
)
//由SipStack产生ListeningPoint
if(IisteningPointDefinition
try(
ssi.1oadConfigurationFile(1isteningPointDe nitionFiIe);
)
catch(SipException X)(
1og(”Warning”,X.getMessage());
)
)
//取出ListeningPoint
lterator i= SS.getListeningPoints();
if(i== nul1)f
log(”Error”.’’No ListeningPoints available on the SipStack:” +
”check configuration file”);
System.exit(一1);
)
//SipStack产生SipProvider,并让SipProvider与ListeningPoint建
//立关联
lp = (ListeningPoint)i.next();
try(
sp = SS.createSipProvider(1p);
)
catch(ListeningPointUnavailabl
log(”Error”,’’Sip provider could not be created on the’’+
” specified listening point”+ x.getMessage(1):
System.exit(一1);
)
//SipProvider与SipListener建立关联
try(
sp.addSipListener(this);
)
catch(TooManyListenersExceptio
log(”Error”.”Could not add SipListener to the’’+
’’SipProvider:Cannot add any more SipListeners to the’’+
”SipProvider”+ x.getMessage());
System.exit(一1);
)
catch(SipListenerAlreadyRegist
log(’’Error”.’’Could not add SipListener to the’’+
”SipProvider:Sip Listener Already Registered : ” +
X.getMessage());
System.exit(一1);
)
本模型其余实体(除个性化服务器)的实现在SIP通信这部分与代理服务器完全相同,各个实体功能的不同是通过在SIP通信的基础上具体逻辑操作的不同实现的,这些操作不属于利用JAIN SIP实现通信的范畴,本文不加详述。