使用WebLogic SIP Server和WebLogic Workshop驱动Cantata媒体服务器
作者:Jeff Bean, Marcelo Oliveira, Sudhrity Mondal
摘要
媒体服务器控制对于大多数基于 SIP 的 VOIP 应用都至关重要。本文介绍了一个使用 BEA WebLogic Workshop 构建的示例会议应用程序,该应用程序利用 BEA WebLogic SIP Server 来驱动 Cantata 的支持 MSCML 的媒体服务器。通过这一基本的音频/视频会议应用程序,我们可以展示媒体服务器控件背后的基本原理,同时提供一些示例,演示如何使用 WebLogic Workshop 开发 SIP servlet,如何将这些 SIP servlet 与使用 WebLogic Workshop 创建的 Java Page Flow 集成,以及如何在 SIP servlet 和 HTTP servlet 之间共享数据。
准备事项
在探讨该应用程序之前,确保您具备以下条件:
- 可从 Cantata 下载的 Snowshore 软件媒体服务器。媒体服务器负责混合构成会议的多个音频和视频流。在本例中,我使用 Cantata 提供的媒体服务器。软件媒体服务器的免费版附带一个两端口的许可证,允许一个 SIP 客户端和 WebLogic SIP Server。如果到Cantata注册,您可以获得带有 90 天评估期试用许可证的不限端口的媒体服务器。有关详细信息,请单击此处。
- 多个运行 SIP 客户端的系统。每个 SIP 客户端将充当一个会议参与者。Counterpath 和 Paradial 等公司都可提供免费或便宜的 SIP 客户端,但所有的 SIP 客户端应该能够正常工作。在本例中,我使用 Counterpath EyeBeam 客户端(可从此处购买)。还有一个免费客户端。
- WebLogic Workshop 8.1
- WebLogic SIP Server 2.1
获得媒体服务器的访问权并确定多个系统来充当 SIP 会议参与方后,就可以安装和配置 WebLogic Workshop 和 WebLogic SIP Server 了。有关安装和配置 WebLogic Workshop 以使用 WebLogic 的文档,请参阅此处。
介绍
媒体服务器控件对于任何涉及以点对点方式(P2P)进行多方通信的基于 SIP 的 VOIP 应用都至关重要。虽然 WebLogic SIP Server 可用来对使用 SIP 的应用程序进行呼叫控制和会话管理,实际的媒体本身仍然需要由媒体服务器来代理。下面是媒体服务器通常执行的任务种类的列表:
- 音频和视频会议,包括混合多个音频流以及在多个换活动视频流之间进行切换
- 播放和录音
- DTMF (双音多频)捕获和识别
- IVR,包括 VoiceXML 解析和浏览
本文展示 BEA 编写的一个会议应用程序,用于演示以下内容:
- 实现与使用 MSCML 的 Cantata(或 Snowshore)Media Server 的互操作性,以播放通告、执行 DTMF 数字收集、建立会议和控制会议
- 使用 WebLogic Workshop 构建 WebLogic SIP Server 应用
- HTTP 和 SIP servlet在同一容器中配合工作,共享业务逻辑
该应用程序提供了允许管理员用户创建会议的 Web 前端。会议创建后,人们可以使用应用程序生成的 SIP ID 呼入此会议。系统会提示呼叫者输入 PIN。PIN 同样是由应用程序生成的,并通过邮件发送给用户(可选)。使用 DTMF 输入 PIN 后,媒体服务器对 PIN 进行处理,应用程序对其进行评估,然后,如果正确,将用户添加到会议中。在会议过程中,可通过 Web UI 对参与者消音、取消消音和终止参与者。这显示了 WebLogic SIP Server 的关键差异因素 —— SIP 和 HTTP 环境之间的信息共享。
因为媒体服务器还支持视频会议,会议参与者还可以随时切换到视频。
整套用例可在附录中找到。
应用程序架构
该应用程序由三个主要组件组成:
- Web 应用程序,提供 HTTP 会议接口。位于项目的“WebApp”文件夹。
- SIP 应用程序,提供管理会议和与媒体服务器通信的呼叫流逻辑。位于“conference”文件夹。
- Conference Manager,Web 和 SIP 应用程序共享的通用业务逻辑。
- SIP proxy/registrar 应用程序,处理 SIP REGISTER 方法和代理传入请求。这以 jar 文件的形式提供。
- Cantata 媒体服务器。
图 1 展示应用程序组件的简单图解:
图 1. 会议参与者通过 SIP 与 Proxy registrar 通话,通过 RTP 与媒体服务器通话(单击图像查看全屏快照)
注意,在图 1 中,请求通过代理传递到与会议应用程序,会议应用程序与媒体服务器一起管理会话。会议管理员使用 Web 应用程序通过 HTTP 配置会议。Web 应用程序和会议应用程序使用 Conference Manager 共享状态。
Web 应用程序
安装说明介绍如何使用 WebLogic Workshop Template 创建 SIP 域,从而可在 WebLogic Workshop 中开发 SIP servlet。这样使您可以在同一应用程序中运行 HTTP Java Page Flow (JPF) 和 SIP servlet ,从而构建聚合的 HTTP/SIP 应用程序。此应用的 HTTP 表示层通过 JPF 实现。SIP 表示层通过 SIP servlet 实现。
应用程序中的 Java Page Flows 和 JSP 定义 Web UI,用来处理用户身份验证、会议创建、监控和管理。每个 UI 功能都有一个相应 JPF 来管理相关 JSP 之间的控制流。
为进行逻辑分离,WebLogic Workshop 项目被划分到两个相关的文件夹中:Web 应用文件夹(WebApp)和会议文件夹(confapp)。WebApp 文件夹包含 HTTP 资源、JSP 和 JSF,用来从 Web UI 处理用户身份验证、会议创建、监控和管理。
会议应用程序
会议文件夹包含 com.bea.appserver.conference 包,这是会议本身背后的业务逻辑(包括通过 SIP servlet 实现的、用于接受参加会议呼叫的呼叫流逻辑,以及用来管理呼叫流的状态控制类)。com.bea.appserver.conferencing.ConferenceManager 类充当 HTTP UI 的接口点。
应用程序使用事件侦听器设计模式从 HTTP 端触发 SIP 操作。例如,当用户断开连接时,会发送一条包含 MSCML 有效负载的 SIP INFO 消息来断开用户。
SIP 对话的细节是由 DialogHandler 接口处理的,同时为 SIP 客户端和 SIP 服务器提供了两种接口实现方式。通过将 SIP 对话状态作为有限状态机概括到单独的业务逻辑中,SIP servlet 编程被大大简化了。这让人想起了 Struts 和 JPF 等基于 MVC 的技术出现之前的 HTTP servlet 世界。可以想象在不久的将来,行业领导者将驱动 JSP、Struts 和 JPF 的扩展,使之涵盖基于 SIP 的表示层。在此之前,在 SIP servlet 应用程序中正确地完成此项任务仍然非常重要。
图 2 演示应用程序的 confapp 部分的简单对象图:
图 2. confapp 应用程序的对象图(单击图像查看全屏快照)
请注意,SIP 呼叫流逻辑是从管理会议的业务逻辑抽象而来的。由 UI 发起的 SIP 对话通过调用 conferee 上的方法表示成信号,该方法调用 DialogHandler 作为其状态更改逻辑的一部分。同样地,由对 com.bea.appserver.conferencing.ConferenceServlet 类的入局请求发起的 SIP 对话也经由在 DialogHandler 中实现的状态机制。通过维护自身的内部状态,DialogHandler 能够轻松地实现 SIP 呼叫流。
驱动媒体服务器
Snowshore IP Media Server 的丰富功能,如播放通告和控制会议,是通过 SIP 消息正文中附带的一种基于 XML 的协议 —— MSCML 驱动的。此应用程序形成 MSCML 来播放通告、建立和解散会议。它还从媒体服务器解析 MSCML,收集用作会议 ID 和 PIN 的 DTMF 数字。此应用程序是特定于 MSCML 的,我还会继续写一些其它文章,介绍如何遵循其它媒体服务器标准,以及如何以更抽象、跨平台的方式与媒体服器进行互操作。
如果您时间有限,那么最简单但最粗放的办法是在 Java String 对象中为应用程序执行的每个独立的媒体服务器操作提供模板 XML。在运行时,应用只需执行关键字替换来动态地配置操作:
public void announceConferee(Conferee user) {
// Here we will not change the state of the conference
// We will simply instruct the conference server to play the prompt
String command = "<mediaservercontrol version="1.0">";
command += "<request>";
command += "<play>";
command += "<prompt>";
command += "<audio url="" + Conferee.baseDir + user.getRecordedName()
+ "">";
command += "<audio url="" + Conferee.JOIN_PROMPT + "">";
command += "</audio>";
command += "</audio>";
command += "</prompt>";
command += "</play>";
command += "</request></mediaservercontrol>";
SipServletRequest req = dialogHandler.session.createRequest("INFO");
try {
req.setContent(command.getBytes(), "application/mediaservercontrol+xml");
req.send();
} catch (Exception e) {
e.printStackTrace();
}
}
随着媒体操作越来越复杂,而且要求从媒体服务器解析 MSCML 消息,扩充我们的工具套件和为媒体服务器控制提供抽象层已成为必要。使用绑定 XML 的框架(如 XMLBeans),利用公共的可用 XML schema 文件获得所需的媒体服务器控制语言是一个不错的开始。本例中采用了 MSCML,并且提供了 XML schema。一旦将 XML 控制语言包含在 XMLBean 中,就可以完成解析附有 XML 有效负载的 SIP INFO 消息等更复杂的任务了。以下代码使用 XMLBean 生成的类来解析从媒体服务器返回到应用服务器的 DTMF 数字:
// Now get the content
try {
String content = new String((byte[]) req.getContent());
// First parse the MSCML response
MediaServerControlDocument doc =
MediaServerControlDocument.Factory.parse(content);
MediaServerControl control = doc.getMediaServerControl();
ResponseType resp = control.getResponse();
String digits = resp.getDigits();
myState = new Connected();
notifyListeners(DialogHandler.AUTHORIZATION_EVENT, digits);
return myState;
} catch (Exception e) {
e.printStackTrace();
}
现在已概要介绍了 XML 层,您可以创建控制 API 来进行一般的媒体服务器控制。请留意将来有关此主题文章。
SIP Servlet最佳实践
应特别注意此应用程序中使用的最佳实践。由于时间关系,并考虑到简单性,这里没有实现所有的最佳实践。此外,SIP servlet规范非常新,一些最佳实践仍在开发中。然而,应关注以下关键实践的细节:
- 根据Web应用程序开发的最佳实践,表示逻辑和业务逻辑要进行分离。会议逻辑在com.bea.appserver.conferencing包中的ConferenceManager类中提供。这允许SIP和HTTP servlet引用同一对象,建立SIP/HTTP聚合。
- 会议状态在SIP servlet之外的业务逻辑中管理。由于SIP servlet是新技术,且会议通过VOIP会话表示,所以人们往往会忘记分离表示和业务逻辑。然而,关键是要认识到SIP servlet是表示层的一部分。这允许在SIP和HTTP之间共享相关信息,例如会议PIN和与会者状态。这也允许使用新的Web UI或SIP呼叫流扩展应用程序。
- 此应用程序考虑到了更大规模的SIP网络。请注意,部署描述符sip.xml文件明确拒绝发送SIP REGISTER请求,因此等于肯定了SIP servlet可以与现有registrar一起部署。事实上,registrar和代理功能是独立提供的。这意味着SIP servlet应是粒度化、模块化和逻辑独立的,以确保在服务创建和部署时获得最佳灵活性。
下载
本文中讨论的以下各项可供下载:
- WebLogic SIP Server用于WebLogic Workshop的域模板
- 会议应用程序的.EAR文件
- 会议应用程序WebLogic Workshop项目
- 会议应用程序安装指南
- Proxy/registrar应用程序
结束语
本文展示了一个示例应用程序,演示了如何使用WebLogic SIP Server和WebLogic Workshop开发聚合的HTTP/SIP应用程序,并介绍了媒体服务器与WebLogic SIP Server的互操作性,以及在多种表示媒体和不同媒体标准下构建基于SIP的应用程序的最佳实践。希望您能够喜欢这个示例。
参考资料
- Dev2Dev WebLogic Server产品中心
- Dev2Dev WebLogic Communications Platform产品中心,包含关于SIP和WebLogic SIP Server的相关文章
- 下载Cantata IP Media Server
- Counterpath EyeBeam SIP Soft phone
- Paradial SIP客户端
- 关于XMLBeans的更多信息,它已经打包在WebLogic Server中
- 要获得背景信息,请参阅Emmanuel Proulx所著的 An Introduction to SIP, Part 1: Meet SIP (中文版,Dev2Dev,2006年4月)和 An Introduction to SIP, Part 2: SIP Servlets (中文版,Dev2Dev,2006年4月)
附录:应用程序用例
以下用例由此应用程序实现。我还提供了到显示相关SIP呼叫流的图的链接。
创建新会议:
- 系统用户使用Web UI登录应用程序。
- 系统用户选择创建新会议,方法是指定主机URI和电子邮件地址。
- 应用程序创建新会议,并将以下会议信息通过电子邮件发送到主机:Conference SIP URI + PIN。
移除会议:
- 系统用户使用Web UI登录应用程序。
- 系统用户选择移除现有会议。
- 此会议被从系统移除。
与会者参加会议:
- 与会者使用提供的Conference SIP URI拨号进入会议,方法是使用SIP客户端(支持的SIP客户端包括Eyebeam和Paradial的Real SIP Client)。
- 会议应用程序检查此会议是否存在。
- 如果此会议不存在,则INVITE会被拒绝。
- 如果此会议存在,且这是第一位参加会议的与会者,则在应用服务器上保留相应的会议资源(呼叫流1、呼叫流2)。
- 随后将此与会者的媒体流连接到Cantata Media Server。
- 应用程序提示与会者,要求输入4位会议PIN码(呼叫流3)。
- 应用程序验证输入的PIN(呼叫流4)。
- 如果PIN是无效的,则应用程序播放错误消息,并提示与会者重试。如果连续三次PIN输入错误,应用程序会断开此用户。
- 输入正确的Conference PIN码后,应用程序播放一条消息,提示用户记录姓名。
- 随后用户被置于会议中,同时会向其他与会者通告其姓名(呼叫流5)。
移除与会者:
- 用户登录到应用程序的Web UI。
- 用户选择监视所有现有会议。
- 用户选择一个会议,然后可以看到当前所有与会者。
- 现在用户可以单击任何与会者,以将其从会议中断开。
屏蔽与会者:
- 用户登录到应用程序的Web UI。
- 用户选择监视所有现有会议。
- 用户选择一个会议,然后可以看到当前所有与会者。
- 现在用户可以单击任何与会者,以屏蔽该与会者(呼叫流6)。
音频和视频会议支持:
- 任何与会者均可仅以音频方式或者以音频和视频方式加入会议。
- Cantata(或Snowshore)媒体服务器将实现激活语音的视频混合,可向其他与会者显示当前讲话者。
与会者离开会议:
- 任何与会者都可以随时决定离开会议,只需执行标准的SIP步骤。
- 如果会议主持人离开会议,则整个会议会被终止。(请注意:目前并不要求在会议开始之前等候会议主持人。)
- · 使用JMX监控应用程序内、外…
- · 实体bean的承诺
- · 并行业务逻辑处理
- · 使用 EJBGen:"一个对三个"
- · HTTP会话对象 VS 有状态EJB
- · WLS 6.0测试中的JNDI 和Web应用
- · WebLogic Server 环境下先进的JMS设计模式
- · 项目推出:针对WLS 7和8.1的COMMONJ WORK MANAGER
- · JMS集群第1部分
- · WebLogic平台的Web SSO(SAML)解决方案
- · WebLogic8中的扩展JSP标签实例解析
- · 解决打开文件过多的问题
- · 使用JMS在集群应用程序中分配任务
- · WebLogic Workshop 8.1 Jav…
- · BEA Workshop8.1之Java Pag…
- · WebLogic Server8.1新功能介…
- · 总结:第一个Java控件
- · 教程:构建第一个Java控件
- · 用WebLogic Workshop开发EJB
- · 用WebLogic Workshop调试应…
- · WLS 9.1与MQ v5.3 通过JMS Bridge通信配置
- · 在Apache Xindice中保存XML文档
- · 升级到WebLogic 9的十大理由
- · 在JAVA EE环境下使用Kodo EJB
- · Weblogic Server 9新特性:J2EE Libraries 和 Optional Packages
- · WebLogic Server 9新特性:JSR-181 Web Services
- · WebLogic Server 9.0:JMS增强功能
- · WebLogic Server9.0产品重点新特性介绍
- · 在Spring中实现事务挂起
- · ALUI 界面深入客户化——替换Portal内置组件
- · ALUI在解决企业门户上的优势
- · AquaLogic User Interaction开发入门
- · 添加协作服务
- · 使用WebLogic SIP Server和WebLogic Workshop驱动Cantata媒体服务器
- · 深入Beehive标签库系列教程 - 前提条件
- · 深入Beehive标签库系列教程(1) - 基本NETUI标签
- · 深入Beehive标签库系列教程(3) - 表单标签:单选框
- · 深入Beehive标签库系列教程(5) - 表单控件:下拉框
