spring+dwrcomet实现无刷新多人聊天室_第1页
spring+dwrcomet实现无刷新多人聊天室_第2页
spring+dwrcomet实现无刷新多人聊天室_第3页
spring+dwrcomet实现无刷新多人聊天室_第4页
spring+dwrcomet实现无刷新多人聊天室_第5页
已阅读5页,还剩4页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

HYPERLINK”/hoojo/archive/2011/06/08/2075201.html”Spring整合DWRcomet实现无刷新多人聊天室用dwr的comet(推)来实现简单的无刷新多人聊天室,comet是长连接的一种。通常我们要实现无刷新,一般会使用到Ajax。Ajax应用程序可以使用两种基本的方法解决这一问题:一种方法是浏览器每隔若干秒时间向服务器发出轮询以进行更新,另一种方法是服务器始终打开与浏览器的连接并在数据可用时发送给浏览器。第一种方法一般利用setTimeout或是setInterval定时请求,并返回最新数据,这无疑增加了服务器的负担,浪费了大量的资源。而第二种方法也会浪费服务器资源,长期的建立连接;而相对第一种来说,第二种方式会更优于第一种方法;这里有一个一对多和多对一的关系,而comet向多个客户端推送数据就是一对多的关系。而具体使用哪种方式,要看你当前的需求而定,没有绝对的。

为什么使用Comet?轮询方法的主要缺点是:当扩展到更多客户机时,将生成大量的通信量。每个客户机必须定期访问服务器以检查更新,这为服务器资源添加了更多负荷.最坏的一种情况是对不频繁发生更新的应用程序使用轮询,例如一种Ajax邮件Inbox.在这种情况下,相当数量的客户机轮询是没有必要的,服务器对这些轮询的回答只会是“没有产生新数据”。虽然可以通过增加轮询的时间间隔来减轻服务器负荷,但是这种方法会产生不良后果,即延迟客户机对服务器事件的感知。当然,很多应用程序可以实现某种权衡,从而获得可接受的轮询方法.尽管如此,吸引人们使用Comet策略的其中一个优点是其显而易见的高效性。客户机不会像使用轮询方法那样生成烦人的通信量,并且事件发生后可立即发布给客户机。但是保持长期连接处于打开状态也会消耗服务器资源。当等待状态的servlet持有一个持久性请求时,该servlet会独占一个线程.这将限制Comet对传统servlet引擎的可伸缩性,因为客户机的数量会很快超过服务器栈能有效处理的线程数量.

如果本示例结合Jetty应用服务器效果会更好.

开发环境:System:WindowsWebBrowser:IE6+、Firefox3+JavaEEServer:tomcat5。0。2。8、tomcat6IDE:eclipse、MyEclipse8开发依赖库:JavaEE5、Spring3。0。5、dwr3Email:hoojo_@126.comBlog:/IBM_hoojohttps:///downloads/dwr/Development%20Builds/Build%20116/dwr.jar”https:///downloads/dwr/Development%20Builds/Build%20116/dwr。jar程序中还需要spring的相关jar包HYPERLINK”http:///repository/app/library/version/detail?name=org.springframework.spring&version=3.0.5。RELEASE"http:///repository/app/library/version/detail?name=org.springframework.spring&version=3.0。5。RELEASE需要的jar包如下

2、建立一个WebProject,名称DWRComet在web.xml中添加dwr、spring配置如下:〈—-加载Spring容器配置—-〉〈listener><listener-class〉org。springframework。web。context.ContextLoaderListener〈/listener-class〉〈/listener〉

〈——设置Spring容器加载配置文件路径—->〈context-param〉<param—name〉contextConfigLocation〈/param—name〉<param—value〉classpath*:applicationContext-*。xml〈/param-value>〈/context-param〉

<listener〉<listener-class>org.directwebremoting.servlet。DwrListener</listener—class〉</listener>

<servlet>〈servlet—name〉dwr—invoker</servlet-name>〈servlet—class>org。directwebremoting.servlet.DwrServlet〈/servlet—class><init-param><param-name〉debug〈/param-name>〈param-value〉true〈/param-value></init—param>〈——dwr的comet控制——〉〈init-param〉<param-name〉pollAndCometEnabled〈/param—name><param—value>true〈/param—value〉</init—param〉〈/servlet>

〈servlet—mapping><servlet-name>dwr-invoker</servlet—name〉<url-pattern〉/dwr/*〈/url—pattern〉</servlet—mapping>

3、在src目录加入applicationContext—beans。xml配置,这个配置专门配置bean对象,用来配置需要注入的对象。<?xmlversion=”1。0"encoding=”UTF—8”?〉<beansxmlns="http:///schema/beans"xmlns:xsi="/2001/XMLSchema-instance”xmlns:aop="/schema/aop”xmlns:tx="/schema/tx"xmlns:util="/schema/util”xmlns:context="http:///schema/context"xsi:schemaLocation="http:///schema/beans/schema/beans/spring—beans-3。0。xsd/schema/aophttp:///schema/aop/spring—aop—3。0.xsdhttp:///schema/tx/schema/tx/spring—tx—3.0。xsdhttp:///schema/utilhttp:///schema/util/spring-util-3.0。xsdhttp:///schema/contexthttp:///schema/context/spring-context-3。0.xsd">〈/beans>

4、在WEB—INF目录添加dwr。xml文件,基本代码如下<?xmlversion="1。0"encoding=”UTF—8”?〉〈!DOCTYPEdwrPUBLIC”—//GetAheadLimited//DTDDirectWebRemoting3。0//EN"”/dwr/dwr30。dtd”><dwr〉</dwr>以上的准备基本完毕,下面来完成无刷新聊天室代码

二、聊天室相关业务实现1、聊天实体类Modelpackagecom.hoo.entity;

importjava。util。Date;

/***〈b〉function:</b>*@authorhoojo*@createDate2011—6—3下午06:40:07*@fileMessage。java*@packagecom.hoo.entity*@projectDWRComet*@bloghttp:///IBM_hoojo*@emailhoojo_@126.com*@version1。0*/publicclassMessage{privateintid;privateStringmsg;privateDatetime;//getter、setter}

2、编写聊天信息的事件packagecom。hoo。chat;

importorg。springframework。context.ApplicationEvent;

/***<b>function:〈/b〉发送聊天信息事件*@authorhoojo*@createDate2011-6-7上午11:24:21*@fileMessageEvent。java*@packagecom。hoo。util*@projectDWRComet*@bloghttp:///IBM_hoojo*@emailhoojo_@126.com*@version1.0*/publicclassChatMessageEventextendsApplicationEvent{

privatestaticfinallongserialVersionUID=1L;

publicChatMessageEvent(Objectsource){super(source);}}继承ApplicationEvent,构造参数用于传递发送过来的消息。这个事件需要一个监听器监听,一旦触发了这个事件,我们就可以向客户端发送消息.

3、发送消息服务类,用户客户端发送消息。dwr需要暴露这个类里面的发送消息的方法packagecom。hoo。chat;

importorg.springframework.beans.BeansException;importorg。springframework。context。ApplicationContext;importorg.springframework。context.ApplicationContextAware;importcom。hoo.entity。Message;

/***<b〉function:〈/b〉客户端发消息服务类业务*@authorhoojo*@createDate2011—6-7下午02:12:47*@fileChatService.java*@packagecom.hoo。chat*@projectDWRComet*@blog/IBM_hoojo*@emailhoojo_@126。com*@version1.0*/publicclassChatServiceimplementsApplicationContextAware{privateApplicationContextctx;publicvoidsetApplicationContext(ApplicationContextctx)throwsBeansException{this。ctx=ctx;}/***〈b〉function:</b〉向服务器发送信息,服务器端监听ChatMessageEvent事件,当有事件触发就向所有客户端发送信息*@authorhoojo*@createDate2011—6—8下午12:37:24*@parammsg*/publicvoidsendMessage(Messagemsg){//发布事件ctx.publishEvent(newChatMessageEvent(msg));}}上面的sendMessage需要浏览器客户端调用此方法完成消息的发布,传递一个Message对象,并且是触发ChatMessageEvent事件。

4、编写监听器监听客户端是否触发ChatMessageEventpackagecom.hoo.chat;

importjava。util。Collection;importjava.util。Date;importjavax.servlet.ServletContext;importorg.directwebremoting。ScriptBuffer;importorg.directwebremoting。ScriptSession;importorg.directwebremoting。ServerContext;importorg。directwebremoting.ServerContextFactory;importorg。springframework.context.ApplicationEvent;importorg.springframework.context。ApplicationListener;importorg。springframework。web。context。ServletContextAware;importcom。hoo.entity.Message;

/***〈b〉function:</b〉监听客户端事件,想客户端推出消息*@authorhoojo*@createDate2011—6-7上午11:33:08*@fileSendMessageClient.java*@packagecom。hoo。util*@projectDWRComet*@blog/IBM_hoojo*@emailhoojo_@126。com*@version1。0*/@SuppressWarnings(”unchecked”)publicclassChatMessageClientimplementsApplicationListener,ServletContextAware{privateServletContextctx;publicvoidsetServletContext(ServletContextctx){this。ctx=ctx;}@SuppressWarnings("deprecation")publicvoidonApplicationEvent(ApplicationEventevent){//如果事件类型是ChatMessageEvent就执行下面操作if(eventinstanceofChatMessageEvent){Messagemsg=(Message)event.getSource();ServerContextcontext=ServerContextFactory.get();//获得客户端所有chat页面scriptsession连接数

Collection<ScriptSession〉sessions=context.getScriptSessionsByPage(ctx.getContextPath()+”/chat.jsp");for(ScriptSessionsession:sessions){ScriptBuffersb=newScriptBuffer();Datetime=msg.getTime();Strings=time.getYear()+”—"+(time.getMonth()+1)+"-"+time。getDate()+""+time.getHours()+":”+time。getMinutes()+”:”+time。getSeconds();//执行setMessage方法

sb.appendScript(”showMessage({msg:'”)。appendScript(msg。getMsg()).appendScript("’,time:'”).appendScript(s).appendScript(”'})");System.out.println(sb.toString());//执行客户端scriptsession方法,相当于浏览器执行JavaScript代码//上面就会执行客户端浏览器中的showMessage方法,并且传递一个对象过去

session。addScript(sb);}}}}上面的代码主要是监听客户端的事件,一旦客户端有触发ApplicationEvent事件或是其子类,就会执行onApplicationEvent方法.代码中通过instanceof判断对象实例,然后再执行.如果有触发ChatMessageEvent事件,就获取所有连接chat.jsp这个页面的ScriptSession。然后像所有的ScriptSession中添加script。这样被添加的ScriptSession就会在有连接chat.jsp的页面中执行。所以这就是客户端为什么会执行服务器端的JavaScript代码。但前提是需要在web.xml中添加dwrComet配置以及在chat页面添加ajax反转。

5、下面开始在bean容器和dwr的配置中添加我们的配置applicationContext-beans。xml配置<beanid=”chatService"class=”com.hoo.chat.ChatService"/>〈beanid="chatMessageClient"class="com.hoo.chat。ChatMessageClient”/>上面的chatService会在dwr配置中用到dwr.xml配置<allow>〈convertmatch=”com.hoo.entity.Message"converter=”bean"〉〈paramname=”include"value=”msg,time"/〉〈/convert〉

<createcreator=”spring”javascript="ChatService"><paramname=”beanName"value=”chatService"/>〈/create>〈/allow>charService的sendMessage方法传递的是Message对象,所以要配置Message对象的convert配置。上面的create的creator是spring,表示在spring容器中拿chatService对象.里面的参数的beanName表示在spring容器中找name等于charService的bean对象。

6、客户端chat。jsp页面代码〈%@pagelanguage="java"import=”java。util。*"pageEncoding="UTF-8"%〉<%Stringpath=request.getContextPath();StringbasePath=request。getScheme()+”://"+request。getServerName()+”:"+request。getServerPort()+path+”/”;%〉

<!DOCTYPEHTMLPUBLIC"—//W3C//DTDHTML4。01Transitional//EN”〉<html>〈head〉<basehref=”<%=basePath%〉”>〈title>Chat〈/title><metahttp-equiv="pragma"content=”no-cache”><metahttp—equiv="cache-control”content=”no—cache”><metahttp—equiv="expires”content="0”>〈scripttype="text/javascript”src=”${pageContext。request。contextPath}/dwr/engine。js"></script〉〈scripttype="text/javascript”src="${pageContext。request.contextPath}/dwr/util。js”></script>〈scripttype=”text/javascript"src="${pageContext.request。contextPath}/dwr/interface/ChatService。js”>〈/script>〈scripttype=”text/javascript"〉functionsend(){vartime=newDate();varcontent=dwr.util。getValue(”content");varname=dwr。util。getValue("userName”);varinfo=encodeURI(encodeURI(name+"say:\n"+content));varmsg={"msg":info,”time”:time};dwr.util.setValue(”content",””);if(!!content){ChatService。sendMessage(msg);}else{alert("发送的内容不能为空!”);}}

functionshowMessage(data){

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论