作者:Nasir Khan
01/31/2007
本文介绍了SIP Servlet编程模型,这是一种以SIP Servlet规范为依据,用于编写SIP应用程序的模型。 文章涵盖了SIP servlet容器和SIP servlet API的细节。 通过阅读本文,您可以对SIP servlet容器的设计动机有一定的理解和认识。 同时了解各种不同的API结构,以及如何利用这些结构创建强大的SIP应用程序。
本文详述了SIP servlet编程模型和SIP servlet API。 想了解关于SIP servlet的入门知识,请阅读Emmanuel Proulx撰写的发表在Dev2Dev上的文章(含两部分):SIP简介,第1部分:SIP初探 (中文版,Dev2Dev,2006年4月)和SIP简介,第2部分:SIP SERVLET(中文版,Dev2Dev,2006年4月)。 要阅读本文,需对SIP协议有基本的理解。 熟悉HTTP servlet模型当然更好,但并非阅读本文的前提条件。 除了SIP协议本身之外,本文还解释了独立于其他标准或规范的概念。 文中涵盖了SIP servlet编程模型,API(SSAPI),以及提供该API的容器。 我们首先将介绍SIP servlet模型的基本知识以及该模型最适用的对象。 然后探究API的重要工件,容器如何使这些工件有效,以及容器该完成哪些任务。再通过实例演示SIP servlet应用程序能做些什么。注意,本文使用的术语SSAPI和SIP Servlet规范是可以互换的。
首先回顾一下为什么SIP Servlet规范对于SIP Java开发人员来说是一个极具吸引力的主张,以及SSAPI的价值主张是什么。 然后将介绍JSR 116 规范对SSAPI规定的一些目标。
SIP servlet规范允许应用程序执行一套相当完整的SIP信令。 SIP协议定义了不同类型的高级SIP角色,如User Agents(明确地说,UA即UA Client、UA Server和Back to Back UA B2BUA<尚有争议>)、Proxy、Registrar、Redirect Server等。 SSAPI是一种强大的API,它允许把上述这些角色编写成SIP servlet应用程序。
SIP是可扩展的协议,通过增加新特性可以扩展其基本协议,这是SIP的优势之一。 事实上,诸多此类RFC都为基本SIP RFC(3261)定义了扩展。 这种扩展机制在很大程度上是通过在容器功能和应用程序之间把SIP处理分开来实现的。 容器执行大多数基本协议处理,而一些高级任务则由应用程序执行。 这种巧妙的任务分割使SSAIP极为强大且具有灵活性。
容器处理一些"非本质"复杂性,如网络、事务、对话管理、via头字段和路由处理。 不同的应用程序对这些处理任务的需求也不同。而让每个应用程序分别都包含这些处理功能显然是多余的。 容器管理所有这些任务,而应用程序则提供一些高级的功能。
部署在SIP servlet容器上的代理应用程序就是一个例子。 在代理过程中,该应用程序会在请求中添加自已的via头字段。 Via头字段是基本SIP协议要求添加的,它显示了请求所经过的网络实体。 via头字段也包含了充当事务标识符的分支标识符。 容器维护事务和与事务相关的状态机,因此在请求中插入via头字段的工作也由容器完成。
下游的SIP实体接收到代理应用程序转发过来的请求后,按原路发回一个响应。 容器接收到这个响应之后,移除它在原始请求中插入的via头字段并处理响应。 注意,应用程序完全不用担心对via头字段的管理,这减轻了应用程序开发人员的负担。 一个容器的某些实例很注意一些普通但基本的协议细节,本文将介绍其中的一部分。
Sip Servlet规范允许应用程序的构建跨越不同的协议/规范。 这是SSAPI最杰出的价值主张之一。 Sip Servlet规范还严密地符合Java EE规范,希望托管SIP servlet应用程序的容器也能使其应用程序具有Java EE的属性——其中最值得一提的就是HTTP Servlet容器。
如图1所示,SSAPI规范以servlet规范为基础,并且平行于HTTP Servlet规范。
图1。 SIP Servlet 规范系谱图
融合应用程序能够同时具备SIP和HTTP的功能,存在大量这样的实例。 然而,事实上,JSR116并没有足够充分地考虑到当前这种形式的融合应用程序。
Sip servlet规范允许几个应用程序针对相同的请求或响应同时执行各自的任务,因此应用程序能够彼此独立地执行。这是SSAPI另一个非常强大的属性。它保证了应用程序开发人员可以提供独立于其他应用程序的附加特性。然后再把这些应用程序结合起来为一次呼叫提供服务。 这里的合成指的是容器的合成。 SSAPI对于这一点的规定并不充分,为不同的实现留下了空间来实现这个功能。 希望这些不足在规范的下一修订版(JSR 289)中会被解决。
应用程序数据可以存储在容器管理的会话对象中,这种对象可用于状态复制和故障转移(failover)。 几乎所有能够执行一些有用功能的应用程序都具有一些不同的请求和响应之间的状态。 有的状态是SIP协议本身需要的。 事务状态机处理其服务器端和客户端事务状态,还有对话状态机。 因此,容器有消息上下文的概念(用于封装SIP级状态)以及会话概念(SSAPI结构)。 然而,应用程序能够在容器维护的Session对象中保存自身状态。 电信级(carrier grade)容器复制这个状态,以使呼叫能对一个容器实例容错。
如您所见,该规范清楚地定义了SIP servlet容器和SIP servlet应用程序的作用域和行为。 下一部分将探究容器功能。
我们已经知道,SSAPI规范不仅详细说明了API,并且还描述了容器功能。 容器是托管(含有)SIP应用程序的服务器。 容器执行许多SIP功能(各种RFC详细说明了这些SIP功能),因此减轻了应用程序的负担。然而,这样也把应用程序公开(通过SSAPI)给了SIP级消息,应用程序能对后者执行各种操作。 因此,通过编写应用程序并将其部署在容器上,可以提供各种电信和多媒体服务。
图2显示了SIP servlet容器的逻辑层。 底部的五层被称作SIP栈,RFC3261详细说明了其功能。作为基于事务的协议,SIP拥有一个定义明确的事务层。 SIP请求后面总是会紧接着一个或多个临时响应和一个最终响应(不包括ACK,ACK没有响应)。事务机用于追踪临时和最终响应。
图2。 SIP servlet容器构成
SIP servlet规范定义了SIP对话的概念。 对话是在两个SIP端点之间的端到端(point-to-point)会话,由对话标识符唯一识别。 并不是所有的SIP请求都创建对话。 创建对话的请求拥有定义明确的建立和撤除对话的机制(即:INVITE、SUBSCRIBE/NOTIFY和REFER请求)。
图2中的SIP栈并非严格符合RFC3261——其差别是:事务层上面还应有一个事务用户(Transaction User,TU)层,此外,对话管理层在3261中并不是一个明确的层。图中所示和RFC中描述的层是逻辑层,并没有把它们转化成物理实现。
因为对话大致对应于、SipSession对象,SipSession对象也和SipApplicationSession(稍后讨论)有关,所以对话层是SIP servlet容器中一个高可见度的要素。 上图中,事务用户(RFC3261中的TU)层实际上在对话管理层和大容器块之间被分开了。 容器的主要目的是托管根据容器所实现的SSAPI编写的SIP servlet应用程序。 容器向应用程序公开对象(例如SipServletRequest、SipServletResponse、各种类型的会话)和工具(例如如计时器和日志记录程序)。因此可以很便捷地开发功能强大的应用程序。
SIP是基于文本的协议,所以易于理解(RFC3261非常精细地定义了SIP协议和基本协议),但是编写SIP应用程序并不是一项容易的工作。 设计SSAPI初衷是使应用程序开发人员能轻松地建立SIP应用程序。 一方面,SSAPI允许访问SIP请求中的所有SIP头字段;另一方面,它不需要应用程序为纠正协议行为理解或修改SIP头字段。 实际上,对于应用程序来说,一些头字段是严格禁止访问的。 SSAPI定义了所谓的系统头字段(System Header),由容器管理――即:From、To、Call-ID、CSeq、Via、Route(不包括pushRoute)和Contact头字段。 应用程序可以对Record-Route头字段添加属性。
Contact头字段是消息中的系统头字段而不是REGISTER请求或响应中的头字段,也不是3xx 或485响应中的头字段。 此外,对于执行可靠临时响应扩展的容器,可以考虑使用Rack和RSeq系统头字段。 简而言之,系统头字段管理原本需要很多SIP级活动,而容器帮助应用程序完成了很多这方面的处理。
From/To/Call-ID/CSeq头字段共同标识一个SIP对话。 我们知道,一些SIP方法(如INVITE和SUBSCRIBE)用于建立一个对话。 SSAPI容器追踪对话状态以及和对话有关的数据,因此为应用程序减去了巨大的负担。 SSAPI容器被指定用于管理Record-Route、Contact和Via头字段,是因为网络监听点、故障管理、多重自引导支持和传送开关都由容器执行。 依靠修改Request-URI和/或添加(pushRoute)Route头字段,应用程序仍能参与容器发出请求的路由决策。由于使用网络级功能(如路由)的应用程序不需要管理网络级资源,从而简化了SSAPI容器上的编程。
页面: 1, 2 |