SIP Servlets同样基于Java Servlet架构, 其API归属于javax.servlet.sip包, 和javax.servlet.http同样扩展自javax.servlet. 不同的是, HTTP Servlets通过Servlet架构实现了HTTP协议, 而SIP Servlet实现了SIP协议.
通过SIP Servlets, 开发人员可以非常简单的开发出复杂的SIP应用程序, 就像HTTP servlets在WEB应用开发中起到的作用一样.
一 组SIP Servlets连同资源和部署描述文件打包后部署并运行在一个容器或SIP应用服务器上的. 容器提供了例如会话状态管理, 事务管理, 重发, 网络连接, 消息调度, 线程管理, 资源管理, 应用程序管理等服务. 应用程序中只需包含高级的消息处理和业务逻辑, 开发人员不再需要在协议本身上投入过多精力, 这使SIP服务的开发成为一件轻而易举的事情.
下面对HTTP serlvet和SIP servlet做了一点比较:
|
HTTP |
SIP |
Servlet class |
HttpServlet |
SipServlet |
Session |
HttpSession |
SipSession |
Application package |
war |
sar |
Deployment Descriptor |
web.xml |
sip.xml |
SIP serlvets继承自javax.servlet.sip.SipServlet, 这个类同HttpServlet一样, 继承自javax.servlet.GenericServlet. SipServlet通过重写的service(ServletRequest request,
ServletResponse response)方法来处理不同的SIP消息.
由于SIP协议是异步的, 所以service方法每次调用时, 其两个参数中只有一个是有效的, 而另一个是null, 例如, 如果收到的SIP消息是一个request, 那么第一个request参数有效, 而response参数为null, 反之亦然.
SipSerlvet 中service方法的默认实现是把SIP消息交给不同的子方法处理. 对请求来说, 是doXXX()方法, 对响应来说是doXXXResponse()方法. 例如, doInvite(SipServletRequest request)方法处理INVITE请求, doSuccessResponse(SipServletResponse response) 处理所有的2XX响应. 通常, 通过重写SipSerlvet类的这些doXXX(), doXXXResponse()方法, 来实现SIP应用的业务逻辑.
创建响应:
在doXXX(SipServletRequest request)中, 可以通过调用javax.servlet.sip.SipServletRequest类的createResponse()方法来创建一个响应, 随后, 调用这个响应的send()方法,将其发送出去.
创建请求:
在一个SIP Servlet中创建一个请求有两种方式, SipSession类的createRequest()方法用于在已经建立的一个会话中创建请求, 创建的请求属于这个已经存在的SipSession. 另一种方法是
javax.servlet.sip.SipFactory 类的createRequest()方法. SipFactory是SIP Servlet API中提供的一个工厂接口, 用于创建Request, Address, URI, Applicaiton session对象, 它的具体实现是由容器提供的, 在SIP Servlet中, 只需要通过ServletContext类的getAttribute("javax.servlet.sip.SipFactory”) 就可以获得一个SipFactory实例。
下面是一个具体的例子:
这个例子是一简单的"Echo"应用, 它接收Windows Messenger发送的Instant Message消息, 再将收到的消息发送回Windows Messenger。
package blog.sample.sipservlet;
import java.io.IOException;
import java.util.HashMap;
import javax.servlet.*;
import javax.servlet.sip.*;
/**
* EchoServlet provides a simple example of a SIP servlet.
* EchoServlet echoes instant messages sent by Windows Messenger.
*/
public class EchoServlet extends SipServlet {
/**
* _address keeps the mapping between sign-in name and actual contact address.
*/
protected HashMap _addresses = new HashMap();
/**
* Invoked for SIP INVITE requests, which are sent by Windows Messenger
* to establish a chat session.
*/
protected void doInvite(SipServletRequest req)
throws IOException, ServletException {
// we accept invitation for a new session by returning 200 OK response
req.createResponse(SipServletResponse.SC_OK).send();
}
/**
* Invoked for SIP REGISTER requests, which are sent by Windows Messenger
* for sign-in and sign-off.
*/
protected void doRegister(SipServletRequest req)
throws IOException, ServletException {
String aor = req.getFrom().getURI().toString().toLowerCase();
synchronized (_addresses) {
// the non-zero value of Expires header indicates a sign-in.
if (req.getExpires() != 0) {
// keep the name/address mapping
_addresses.put(aor, req.getAddressHeader("Contact").getURI());
}
// the zero value of Expires header indicates a sign-off.
else {
// remove the name/address mapping
_addresses.remove(aor);
}
}
// we accept the sign-in or sign-off by returning 200 OK response
req.createResponse(SipServletResponse.SC_OK).send();
}
/**
* Invoked for SIP MESSAGE requests, which are sent by Windows Messenger
* for instant messages.
*/
protected void doMessage(SipServletRequest req)
throws IOException, ServletException {
SipURI uri = null;
synchronized (_addresses) {
// get the previous registered address for the sender
uri = (SipURI) _addresses.get(req.getFrom().getURI().toString().toLowerCase());
}
if (uri == null) {
// reject the message if it is not from a registered user
req.createResponse(SipServletResponse.SC_FORBIDDEN).send();
return;
}
// we accept the instant message by returning 200 OK response.
req.createResponse(SipServletResponse.SC_OK).send();
// create an echo SIP MESSAGE request with the same content
SipServletRequest echo = req.getSession().createRequest("MESSAGE");
String charset = req.getCharacterEncoding();
if (charset != null) {
echo.setCharacterEncoding(charset);
}
echo.setRequestURI(uri);
echo.setContent(req.getContent(), req.getContentType());
// send the echo MESSAGE request back to Windows Messenger
echo.send();
}
/**
* Invoked for SIP 2xx class responses.
*/
protected void doSuccessResponse(SipServletResponse resp)
throws IOException, ServletException {
// print out when the echo message was accepted.
if (resp.getMethod().equalsIgnoreCase("MESSAGE")) {
System.out.println("\"" + resp.getRequest().getContent()
+ "\" was accepted: " + resp.getStatus());
}
}
/**
* Invoked for SIP 4xx-6xx class responses
*/
protected void doErrorResponse(SipServletResponse resp)
throws IOException, ServletException {
// print out when the echo message was rejected/
if (resp.getMethod().equalsIgnoreCase("MESSAGE")) {
System.out.println("\"" + resp.getRequest().getContent()
+ "\" was rejected: " + resp.getStatus());
}
}
/**
* Invoked for SIP BYE requests, which are sent by Windows Messenger
* to terminate a chat session/
*/
protected void doBye(SipServletRequest req)
throws IOException, ServletException {
// accept session termination by returning 200 OK response.
req.createResponse(SipServletResponse.SC_OK).send();
}
}
EchoServlet的呼叫流程如图:
编译EchoServlet需要servlet.jar和sipservlet.jar这两个jar文件在classpath中. sipservlet.jar可以在JSR116的发布包中找到.
和HTTP Servlet应用一样, SIP Servlet应用同样需要一个部署描述文件-sip.xml. 下面是一个sip.xml的例子:
PUBLIC "-//Java Community Process//DTD SIP Application 1.0//EN"
"http://www.jcp.org/dtd/sip-app_1_0.dtd">
<sip-app>
<display-name>SIP Servlet Sample</display-name>
<servlet>
<servlet-name>echo</servlet-name>
<servlet-class>com.micromethod.sample.EchoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>echo</servlet-name>
<pattern>
<or>
<equal>request.method<value>REGISTER</value></equal>
<equal>request.method<value>INVITE</value></equal>
</or>
</pattern>
</servlet-mapping>
</sip-app>
明 显和web.xml不同的就是用and, or, not, equal, exists, contains, subdomain-of这一系列标签代替了url-pattern. 通过这些标签的组合嵌套,形成了一个条件表达式,表明相应的servlet可以处理哪些SIP消息.
上 面的sip.xml就表明了EchoServlet可以处理REGISTER和INVITE请求. 注意的是, 请求的类型指的是创建会话的请求, 会话后续请求不再做这种条件判断,例如INVITE创建会话后,会话内的ACK, CANCEL, MESSAGE, BYE等消息会直接被判定为由接收INVITE请求的servlet处理。
为 了方便部署, 需要将EchoServlet和sip.xml放入一个部署包中. 和HTTP Servlet应用类似, SIP Servlet应用使用SIP application archive (SAR). SAR文件其实就是JAR文件, 它的内部目录结构和WAR文件相同:
.../WEB-INF
|-- classes
| |-- blog
| |-- sample
| |-- sipservlet
| |-- EchoServlet.class
|-- sip.xml
在上级目录执行jar cv0f echo.sar创建sar文件.
最 后需要做的就是部署echo.sar, 目前提供SIP应用服务器免费下载的的似乎只有BEA和Micromethod, BEA的Weblogic SIP Server是基于它的Web Server实现的, 和J2EE结合比较紧密, 但相应配置运行较为复杂, Micromethod的SIPMethod Application Server相比之下是一个轻量级的产品, 配置部署运行都比较简洁,同时还提供一个方便开发SIP应用的Application Creation Environment和一些基于SIP Servlet技术的完整SIP基础应用,如Proxy Server, Presence Server等, 因此, 比较适合学习和开发使用. 可以从
http://www.micromethod.com或
http://cn.micromethod.com下载.
本 文中使用的就是Micromethod的SIPMethod Application Server, 下载安装后,将echo.sar拷贝到SIPMethod AS的sipapps目录, 最好把sipapps目录下其它的sar文件都删除,以免EchoServlet的servlet-mapping和其它应用中的servlet冲突. 接下来, 执行SIPMethod的bin目录下的startup.bat运行服务器, 在服务器启动过程中,echo.sar就会被解开.
通 常情况下, 运行SIPMethod AS甚至不需要额外配置, 使用它的默认配置就可以运行, 高级的配置方式可以参考它的user-guide. 常见的问题是端口冲突, SIPMethod AS默认需要占用TCP5060, TCP8080, TCP47492, UDP5060这四个端口.
当SIPMethod Application Server启动完成后, 就可以用Windows Messenger看效果了.
Windows Messenger的需要5.0或更高, 低于这个版本的WM没有SIP功能.
运行Windows Messenger, 依照下面的步骤进行配置:
1. 打开"Options"对话框 Tools->Options;
2. 点击"Options"对话框中的"Account"标签;
3. 选中"My contacts include users of a SIP Communications Service"复选框;
4. 在"Sign-in name"编辑框中输入一个SIP URI, 例如 kyle@micromethod.com;
5. 点击"Advanced..."按钮打开"SIP Communications Service Connection Configuration"对话框;
6. 选中"Configure settings"单选按钮;
7. 在"Server name or IP address"编辑框中输入运行SIPMethod AS的机器IP地址, 例如192.168.0.101, 或192.168.0.101:5060, 5060是SIPMethod 默认的SIP监听端口;
8. 选择使用的传输协议, 通常是TCP或UDP, TLS需要服务器进行额外配置.
配置完成后, 就可以登陆Windows Messenger了, 使用的登陆名就是刚才输入的SIP URI, 例如kyle@micromethod.com.
确保SIPMethod Applicaiton Server是运行的.
接下来选择"Actions->Send an Instant Message…"菜单项, 打开"Send an Instant Message"对话框, 选中对话框的Other标签, 在编辑框中输入echo@micromethod.com, 点击OK. (实际上在这个输入echo或是其它任何字符都可以, 因为我们在servlet-mapping中并没有对request.to或request.uri进行任何限制).
在打开的Instant message窗口中, 就可以和EchoServlet对话了.
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=796426
分享到:
相关推荐
通过这个“servlet 监听器范例”,我们不仅学习了如何使用Servlet监听器来统计在线用户,还了解了如何跟踪用户登录状态。这个示例对于理解和实现在Java Web应用程序中进行用户管理、监控系统活动具有很大的价值。
在Servlet编程中,Servlet初始化参数和ServletContext对象是两个至关重要的概念。这些概念是构建Web应用程序的基础,特别是当涉及到服务器端的动态处理和应用配置时。 Servlet初始化参数是用于配置Servlet的特定...
Servlet编程范例(5)主要探讨的是Web应用程序中的会话管理,这是在开发动态网站时至关重要的概念。会话管理允许服务器在无状态的HTTP协议上保持对用户行为的跟踪,使得服务器能够识别和处理来自同一用户的连续请求...
在"Jsp&Servlet完整范例Gossip"中,可能包含了各种应用场景,如用户登录、注册、数据查询、提交表单等,通过实际操作可以帮助初学者深入理解JSP和Servlet如何协同工作,以及Model2架构的实现方式。文件列表中的...
Java Web Servlet程序范例是基于Java技术开发的Web应用程序,主要用以处理HTTP请求并返回响应。在Web应用中,Servlet扮演着服务器端组件的角色,它扩展了Web服务器的功能,使得开发者可以创建动态、交互式的网页。这...
Servlet是Java技术中用于开发Web应用的核心组件,它扩展了Web服务器的功能,使得服务器能够处理动态内容和交互性需求。Servlet是一个服务器端的Java应用程序,它可以接收并响应来自客户端(通常是Web浏览器)的HTTP...
SuperMap Objects 2008 为广大用户提供了在五种开发语言下(VB6,VC++6,VB .NET2005,C# .NET2005,Delphi7)共240个详细的范例工程源代码及可执行程序,每个工程都是针对某一个或一些具体功能来组织和编写的,相...
在本文中,我们将深入探讨一个简单的Servlet示例,以及如何配置和使用Servlet来处理网页交互。 首先,我们来看第一个Servlet示例,它的主要任务是接收到HTTP GET请求后,向客户端返回一个简单的文本消息"hello ...
资源名称:Java范例开发大全教学视频及源码(22集)资源目录:【】Java范例开发大全教学视频及源码01【】Java范例开发大全教学视频及源码02【】Java范例开发大全教学视频及源码03【】Java范例开发大全教学视频及源码...
Servlet 传参详解 Servlet 是一个运行在服务器端的单实例多线程的服务器端 Java 应用程序。理解 Servlet 的生命周期和接受参数信息是掌握 Servlet 技术的关键。 Servlet 的生命周期 Servlet 的生命周期可以分为四...
当Servlet容器首次遇到对应的Servlet类时,会创建Servlet的实例,并调用`init()`方法进行初始化。`init()`方法仅执行一次,通常用于配置Servlet。在服务阶段,每当有新的HTTP请求到达,Servlet容器会在单独的线程中...
在Java Web开发中,Servlet和Filter是两个非常重要的概念。Servlet是Java提供的一个用于扩展服务器功能的接口,而Filter则是一种动态web资源过滤机制,它允许我们在数据处理流程中进行预处理和后处理,比如登录验证...
在JAVAEE web开发中,Servlet扮演着核心角色,它提供了服务器端动态处理和响应客户端请求的能力。本实例主要探讨Servlet中的两个关键对象:HttpServletRequest(Request)和HttpServletResponse(Response),它们是...
Chapter15 函数、公式及数组实用操作技巧 Chapter16 程序流程控制实用操作技巧 Chapter17 打印工作表实用操作技巧 Chapter18 VBA工程实用操作技巧 Chapter19 文件和文件夹实用操作技巧 Chapter20 其他Office应用程序...
范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50范例50...
Ajax TreeView 控件及范例
根据提供的文件信息,“军用产品研制技术文件编写范例 范例11 软件开发计划 22P 8.7M.pdf”,我们可以分析出这份文档主要讲述的是军用产品软件开发计划的编写范例。接下来,我们将详细探讨军用产品软件开发计划中的...
公路工程资料填写与组卷范例.pdf
范例1-1 一维数组的倒置 2 ∷相关函数:fun函数 1.1.2 一维数组应用 3 范例1-2 一维数组应用 3 1.1.3 一维数组的高级应用 5 范例1-3 一维数组的高级应用 5 1.1.4 显示杨辉三角 7 范例1-4 显示杨辉三角 7 ∷...
《C语言开发范例大全》是一本深受C语言学习者喜爱的教材,它以其丰富的实例和详尽的解析,为初学者和有经验的程序员提供了深入理解C语言的宝贵资源。这本书涵盖了C语言的基础概念、语法特性、高级编程技巧以及实际...