91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何利用Spring整合DWR comet 實現無刷新的多人聊天室

發布時間:2021-06-17 16:06:05 來源:億速云 閱讀:148 作者:chen 欄目:編程語言

這篇文章主要介紹“如何利用Spring整合DWR comet 實現無刷新的多人聊天室”,在日常操作中,相信很多人在如何利用Spring整合DWR comet 實現無刷新的多人聊天室問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何利用Spring整合DWR comet 實現無刷新的多人聊天室”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

用dwr的comet(推)來實現簡單的無刷新多人聊天室,comet是長連接的一種。通常我們要實現無刷新,一般會使用到Ajax。Ajax 應用程序可以使用兩種基本的方法解決這一問題:一種方法是瀏覽器每隔若干秒時間向服務器發出輪詢以進行更新,另一種方法是服務器始終打開與瀏覽器的連接并在數據可用時發送給瀏覽器。***種方法一般利用setTimeout或是setInterval定時請求,并返回***數據,這無疑增加了服務器的負擔,浪費了大量的資源。而第二種方法也會浪費服務器資源,長期的建立連接;而相對***種來說,第二種方式會更優于***種方法;這里有一個一對多和多對一的關系,而comet向多個客戶端推送數據就是一對多的關系。而具體使用哪種方式,要看你當前的需求而定,沒有絕對的。

為什么使用Comet?

輪詢方法的主要缺點是:當擴展到更多客戶機時,將生成大量的通信量。每個客戶機必須定期訪問服務器以檢查更新,這為服務器資源添加了更多負荷。最壞的一種情況是對不頻繁發生更新的應用程序使用輪詢,例如一種 Ajax 郵件 Inbox。在這種情況下,相當數量的客戶機輪詢是沒有必要的,服務器對這些輪詢的回答只會是 “沒有產生新數據”。雖然可以通過增加輪詢的時間間隔來減輕服務器負荷,但是這種方法會產生不良后果,即延遲客戶機對服務器事件的感知。當然,很多應用程序可以實現某種權衡,從而獲得可接受的輪詢方法。

盡管如此,吸引人們使用 Comet 策略的其中一個優點是其顯而易見的高效性。客戶機不會像使用輪詢方法那樣生成煩人的通信量,并且事件發生后可立即發布給客戶機。但是保持長期連接處于打開狀態也會消耗服務器資源。當等待狀態的 servlet 持有一個持久性請求時,該 servlet 會獨占一個線程。這將限制 Comet 對傳統 servlet 引擎的可伸縮性,因為客戶機的數量會很快超過服務器棧能有效處理的線程數量。

如果本示例結合Jetty應用服務器效果會更好。

開發環境:

System:Windows

WebBrowser:IE6+、Firefox3+

JavaEE Server:tomcat5.0.2.8、tomcat6

IDE:eclipse、MyEclipse 8

開發依賴庫:

JavaEE5、Spring 3.0.5、dwr 3

Email:hoojo_@126.com

Blog:http://blog.csdn.net/IBM_hoojo or http://hoojo.cnblogs.com/

一、準備工作

1、 下載dwr的相關jar包

https://java.net/downloads/dwr/Development%20Builds/Build%20116/dwr.jar

程序中還需要spring的相關jar包

http://ebr.springsource.com/repository/app/library/version/detail?name=org.springframework.spring&version=3.0.5.RELEASE

需要的jar包如下

如何利用Spring整合DWR comet 實現無刷新的多人聊天室

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對象,用來配置需要注入的對象。

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:aop="http://www.springframework.org/schema/aop"     xmlns:tx="http://www.springframework.org/schema/tx"       xmlns:util="http://www.springframework.org/schema/util"     xmlns:context="http://www.springframework.org/schema/context"     xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd      http://www.springframework.org/schema/aop       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd      http://www.springframework.org/schema/tx       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd      http://www.springframework.org/schema/util       http://www.springframework.org/schema/util/spring-util-3.0.xsd      http://www.springframework.org/schema/context       http://www.springframework.org/schema/context/spring-context-3.0.xsd"> </beans>

4、 在WEB-INF目錄添加dwr.xml文件,基本代碼如下

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr/dwr30.dtd"> <dwr> </dwr>

以上的準備基本完畢,下面來完成無刷新聊天室代碼

二、聊天室相關業務實現

1、 聊天實體類Model

package com.hoo.entity;     import java.util.Date;     /**   * <b>function:</b>   * @author hoojo   * @createDate 2011-6-3 下午06:40:07   * @file Message.java   * @package com.hoo.entity   * @project DWRComet   * @blog http://blog.csdn.net/IBM_hoojo   * @email hoojo_@126.com   * @version 1.0   */ public class Message {      private int id;      private String msg;      private Date time;      //getter、setter  }

2、 編寫聊天信息的事件

package com.hoo.chat;     import org.springframework.context.ApplicationEvent;     /**   * <b>function:</b>發送聊天信息事件   * @author hoojo   * @createDate 2011-6-7 上午11:24:21   * @file MessageEvent.java   * @package com.hoo.util   * @project DWRComet   * @blog http://blog.csdn.net/IBM_hoojo   * @email hoojo_@126.com   * @version 1.0   */ public class ChatMessageEvent extends ApplicationEvent {         private static final long serialVersionUID = 1L;         public ChatMessageEvent(Object source) {          super(source);      }  }

繼承ApplicationEvent,構造參數用于傳遞發送過來的消息。這個事件需要一個監聽器監聽,一旦觸發了這個事件,我們就可以向客戶端發送消息。

3、 發送消息服務類,用戶客戶端發送消息。dwr需要暴露這個類里面的發送消息的方法

package com.hoo.chat;     import org.springframework.beans.BeansException;  import org.springframework.context.ApplicationContext;  import org.springframework.context.ApplicationContextAware;  import com.hoo.entity.Message;     /**   * <b>function:</b>客戶端發消息服務類業務   * @author hoojo   * @createDate 2011-6-7 下午02:12:47   * @file ChatService.java   * @package com.hoo.chat   * @project DWRComet   * @blog http://blog.csdn.net/IBM_hoojo   * @email hoojo_@126.com   * @version 1.0   */ public class ChatService implements ApplicationContextAware {      private ApplicationContext ctx;      public void setApplicationContext(ApplicationContext ctx) throws BeansException {          this.ctx = ctx;      }            /**       * <b>function:</b> 向服務器發送信息,服務器端監聽ChatMessageEvent事件,當有事件觸發就向所有客戶端發送信息       * @author hoojo       * @createDate 2011-6-8 下午12:37:24       * @param msg       */     public void sendMessage(Message msg) {          //發布事件          ctx.publishEvent(new ChatMessageEvent(msg));      }  }

上面的sendMessage需要瀏覽器客戶端調用此方法完成消息的發布,傳遞一個Message對象,并且是觸發ChatMessageEvent事件。

4、 編寫監聽器監聽客戶端是否觸發ChatMessageEvent

package com.hoo.chat;     import java.util.Collection;  import java.util.Date;  import javax.servlet.ServletContext;  import org.directwebremoting.ScriptBuffer;  import org.directwebremoting.ScriptSession;  import org.directwebremoting.ServerContext;  import org.directwebremoting.ServerContextFactory;  import org.springframework.context.ApplicationEvent;  import org.springframework.context.ApplicationListener;  import org.springframework.web.context.ServletContextAware;  import com.hoo.entity.Message;     /**   * <b>function:</b>監聽客戶端事件,想客戶端推出消息   * @author hoojo   * @createDate 2011-6-7 上午11:33:08   * @file SendMessageClient.java   * @package com.hoo.util   * @project DWRComet   * @blog http://blog.csdn.net/IBM_hoojo   * @email hoojo_@126.com   * @version 1.0   */ @SuppressWarnings("unchecked")  public class ChatMessageClient implements ApplicationListener, ServletContextAware {            private ServletContext ctx;      public void setServletContext(ServletContext ctx) {          this.ctx = ctx;      }            @SuppressWarnings("deprecation")      public void onApplicationEvent(ApplicationEvent event) {          //如果事件類型是ChatMessageEvent就執行下面操作          if (event instanceof ChatMessageEvent) {              Message msg = (Message) event.getSource();              ServerContext context = ServerContextFactory.get();              //獲得客戶端所有chat頁面script session連接數                 Collection<ScriptSession> sessions = context.getScriptSessionsByPage(ctx.getContextPath() + "/chat.jsp");              for (ScriptSession session : sessions) {                  ScriptBuffer sb = new ScriptBuffer();                  Date time = msg.getTime();                  String s = 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());                  //執行客戶端script session方法,相當于瀏覽器執行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配置

<bean id="chatService" class="com.hoo.chat.ChatService"/> <bean id="chatMessageClient" class="com.hoo.chat.ChatMessageClient"/>

上面的chatService會在dwr配置中用到

dwr.xml配置

<allow>     <convert match="com.hoo.entity.Message" converter="bean">         <param name="include" value="msg,time" />     </convert>        <create creator="spring" javascript="ChatService">         <param name="beanName" value="chatService" />     </create> </allow>

charService的sendMessage方法傳遞的是Message對象,所以要配置Message對象的convert配置。

上面的create的creator是spring,表示在spring容器中拿chatService對象。里面的參數的beanName表示在spring容器中找name等于charService的bean對象。

6、 客戶端chat.jsp頁面代碼

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%  String path = request.getContextPath();  String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  %>    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html>   <head>     <base href="<%=basePath%>">           <title>Chat</title>           <meta http-equiv="pragma" content="no-cache">     <meta http-equiv="cache-control" content="no-cache">     <meta http-equiv="expires" content="0">          <script type="text/javascript" src="${pageContext.request.contextPath }/dwr/engine.js"></script>     <script type="text/javascript" src="${pageContext.request.contextPath }/dwr/util.js"></script>     <script type="text/javascript" src="${pageContext.request.contextPath }/dwr/interface/ChatService.js"></script>     <script type="text/javascript">         function send() {              var time = new Date();              var content = dwr.util.getValue("content");              var name = dwr.util.getValue("userName");              var info = encodeURI(encodeURI(name + " say:\n" + content));              var msg = {"msg": info, "time": time};              dwr.util.setValue("content", "");              if (!!content) {                  ChatService.sendMessage(msg);              } else {                  alert("發送的內容不能為空!");              }          }             function showMessage(data) {              var message = decodeURI(decodeURI(data.msg));              var text = dwr.util.getValue("info");              if (!!text) {                    dwr.util.setValue("info", text + "\n" + data.time + "  " + message);              } else {                  dwr.util.setValue("info", data.time + "  " + message);              }          }      </script>   </head>       <body onload="dwr.engine.setActiveReverseAjax(true);">       <textarea rows="20" cols="60" id="info" readonly="readonly"></textarea>       <hr/>       昵稱:<input type="text" id="userName"/><br/>       消息:<textarea rows="5" cols="30" id="content"></textarea>       <input type="button" value=" Send " onclick="send()" style="height: 85px; width: 85px;"/>   </body> </html>

首先,你需要導入dwr的engine.js文件,這個很重要,是dwr的引擎文件。其次你使用的那個類的方法,也需要在導入進來。一般是interface下的,并且在dwr.xml中配置過的create。

上面的js中調用的charService類中的sendMessage方法,所以在jsp頁面中導入的是ChatService.js。

在body的onload事件中,需要設置反轉Ajax,這個很重要。

showMessage是ChatMessageClient的onApplicationEvent方法中的appendScript中需要執行的方法。data參數也是在那里傳遞過來的。

每當發送sendMessage方法后就會觸發ChatMessageEvent事件,然后監聽的地方就會執行onApplicationEvent方法,在這個方法中又會執行瀏覽器中的showMessage方法。

如何利用Spring整合DWR comet 實現無刷新的多人聊天室

到此,關于“如何利用Spring整合DWR comet 實現無刷新的多人聊天室”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

金堂县| 罗平县| 都江堰市| 富蕴县| 玛多县| 宁德市| 正宁县| 石棉县| 阿拉善左旗| 黄骅市| 衡阳市| 临沧市| 玉田县| 正阳县| 通山县| 香格里拉县| 六安市| 阳山县| 镇康县| 威远县| 罗定市| 松滋市| 晋江市| 左云县| 斗六市| 石屏县| 新兴县| 江门市| 漠河县| 河池市| 沈丘县| 星子县| 丹东市| 罗江县| 宝坻区| 荔波县| 龙南县| 防城港市| 西乌珠穆沁旗| 山丹县| 五台县|