Using Dwr's Comet (push) for a simple no-refresh multiplayer chat room, comet is a long-connected one. Usually we want to implement no refresh, and generally use Ajax. Ajax applications can solve this problem in two basic ways: one is to poll the server for updates every few seconds, and the server always opens a connection to the browser and sends it to the browser when the data is available. The first method generally uses settimeout or setinterval timing requests, and returns the latest data, which undoubtedly increases the burden on the server and wastes a lot of resources. The second method also wastes server resources and establishes connections over a long period of time, whereas the second approach is better than the first, with a one-to-many and many-to-one relationship, and comet pushing data to multiple clients is a one-to-many relationship. and the specific use of which way, depends on your current needs, there is no absolute.
Why use Comet?
The main disadvantage of the polling method is that when extended to more clients, a large amount of traffic is generated. Each client must periodically access the server to check for updates, which adds more load to the server resources. In the worst case, polling is used for applications that do not occur frequently, such as an Ajax message Inbox. In this case, a significant number of client polling is not necessary, and the server's response to these polls will only be "no new data generated". Although the server load can be mitigated by increasing the polling interval, this approach has the undesirable consequence of delaying the client's perception of server events. Of course, many applications can implement some kind of trade-off to get an acceptable polling method.
Nonetheless, one of the advantages of attracting people to use Comet strategy is its obvious efficiency. The client does not generate annoying traffic as it does with a polling method, and it can be published to the client immediately after the event occurs. However, keeping a long-term connection open also consumes server resources. When a servlet waiting for a state holds a persistent request, the servlet will monopolize a thread. This limits the scalability of Comet to the traditional servlet engine, because the number of clients can quickly exceed the number of threads that the server stack can handle efficiently.
This example is better when combined with the Jetty application server.
First, the preparatory work
1. Download DWR related jar Package
Https://java.net/downloads/dwr/Development%20Builds/Build%20116/dwr.jar
Spring related jar Packages are also required in the program
http://ebr.springsource.com/repository/app/library/version/detail?name=org.springframework.spring&version= 3.0.5.RELEASE
The required jar packages are as follows
2, establish a webproject, name Dwrcomet
In Web. XML, add DWR, spring configuration as follows:
<span style= "FONT-SIZE:18PX;" ><?xml version= "1.0" encoding= "UTF-8"? ><web-app xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns= "Http://java.sun.com/xml/ns/javaee" xsi:schemalocation= "Http://java.sun.com/xml/ns/javaee/http Java.sun.com/xml/ns/javaee/web-app_2_5.xsd "id=" webapp_id "version=" 2.5 "><!--load Spring container configuration-->< Listener><listener-class>org.springframework.web.context.contextloaderlistener</listener-class> </listener><!--Set Spring container load profile path--><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's Comet control-->< 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><welcome-file-list>< Welcome-file>chat.jsp</welcome-file></welcome-file-list></web-app></span>
3, Join the Applicationcontext-beans.xml configuration in the SRC directory, which configures the Bean object specifically to configure the objects that need to be injected.
<span style= "FONT-SIZE:18PX;" ><?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"><bean id=" Chatservice "class=" Com.tgb.chat.ChatService "/><bean id=" chatmessageclient "class=" Com.tgb.chat.ChatMessageClient "/></beans></span>
4, add dwr.xml file in Web-inf directory, the basic code is as follows
<span style= "FONT-SIZE:18PX;" ><?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></span>
The above preparation basically finished, below to complete no refresh chat room code
Second, chat room related business realization
1, Chat entity Class model
<span style= "FONT-SIZE:18PX;" >package Com.tgb.entity;import Java.util.date;public class Message {private int id;private String msg;private Date Tim e;public int getId () {return ID;} public void setId (int id) {this.id = ID;} Public String getmsg () {return msg;} public void Setmsg (String msg) {this.msg = msg;} Public Date GetTime () {return time;} public void SetTime (Date time) {this.time = time;}} </span>
2, the event of writing chat information
<span style= "FONT-SIZE:18PX;" >package Com.tgb.chat;import Org.springframework.context.applicationevent;public class ChatMessageEvent extends applicationevent { private static final long serialversionuid = 1L; Public chatmessageevent (Object source) { super (source); }} </span>
inherits Applicationevent, which is used to pass messages sent over. This event requires a listener to listen, and once this event is triggered, we can send a message to the client.
3, send the Message service class, the user client sends the message. Dwr needs to expose the method of sending messages inside this class
<span Style= "FONT-SIZE:18PX;" >package Com.tgb.chat;import Org.springframework.beans.beansexception;import Org.springframework.context.applicationcontext;import Org.springframework.context.ApplicationContextAware; Import Org.springframework.context.applicationeventpublisher;import Com.tgb.entity.message;public class Chatservice implements Applicationcontextaware {private ApplicationContext ctx; public void Setapplicationcontext (ApplicationContext ctx) throws beansexception {this.ctx = CTX; /** * <b>function:</b> sends information to the server, the server listens to the Chatmessageevent event, and sends the message to all clients when an event is triggered * @author Hoojo * @createDate 2011-6-8 pm 12:37:24 * @param msg */public void SendMessage (Message msg) {//Publish Event Ctx.publishevent (New Chatmessageevent (msg)); } public void Init () {}}</span>
The above SendMessage requires the browser client to call this method to complete the publication of the message, pass a Message object, and trigger the Chatmessageevent event.
4. Write listener to monitor whether the client is triggering chatmessageevent
<span style= "FONT-SIZE:18PX;" >package com.tgb.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.tgb.entity.Message; @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) {//If the event type is chat Messageevent performs the following operation if (event instanceof chatmessageevent) {Message msg = (message) Event.getsource (); SErvercontext context = Servercontextfactory.get (); Get client All Chat page script session connection number collection<scriptsession> sessions = context.getscriptsessionsbypage (CT X.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.geth Ours () + ":" + time.getminutes () + ":" + time.getseconds (); Execute the Setmessage method Sb.appendscript ("ShowMessage ({msg: ')"). Appendscript (Msg.getmsg ()) . Appendscript ("', Time: '"). Appendscript (s). Appendscript ("'})"); System.out.println (Sb.tostring ()); Executes the client script session method, equivalent to the browser executing JavaScript code//above will execute the ShowMessage method in the client browser, and pass an object past SES Sion.addScript (SB); }}}}</span>
The above code mainly listens to the client's events, and once the client has triggered the Applicationevent event or its subclasses, the Onapplicationevent method is executed. The object instance is judged by instanceof in the code and then executed. If there is a trigger chatmessageevent event, get all Connections chat.jsp this page scriptsession. Then add script like all the scriptsession. The added scriptsession will be executed on the page with the connection chat.jsp.
So that's why the client executes the server-side JavaScript code. But only if you need to add the Dwrcomet configuration to Web. XML and add Ajax reversals to the chat page.
5. Start adding our configuration in the Bean container and DWR configuration
Applicationcontext-beans.xml Configuration
<span style= "FONT-SIZE:18PX;" ><bean id= "Chatservice" class= "Com.hoo.chat.ChatService"/><bean id= "chatmessageclient" class= " Com.hoo.chat.ChatMessageClient "/></span>
The above Chatservice will be used in the DWR configuration.
Dwr.xml Configuration
<span style= "FONT-SIZE:18PX;" ><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></span>
The Charservice SendMessage method passes the Message object, so you configure the convert configuration of the message object.
The creator of the above create is spring, which indicates that the Chatservice object is taken in the spring container. The beanname of the parameters inside indicates that the Bean object with name equals Charservice is found in the spring container.
6, the Client chat.jsp page code
<span style= "FONT-SIZE:18PX;" ><%@ page language= "java" import= "java.util.*" pageencoding= "UTF-8"%><%string path = Request.getcontextpath (); String basepath = request.getscheme () + "://" + request.getservername () + ":" + request.getserverport () + path + "/";%>&L t;! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" >
First, you need to import the DWR engine.js file, which is very important, is the DWR engine file. Second, the method of the class that you use, also need to import in. It is generally interface under, and is configured in the Dwr.xml create.
The SendMessage method in the Charservice class is called in the above JS, so the chatservice.js is imported in the JSP page.
In the body's onload event, it is important to set the inverse of Ajax.
ShowMessage is a method that needs to be performed in Appendscript in the Onapplicationevent method of Chatmessageclient. The data parameter is also passed over there.
The Chatmessageevent event is triggered whenever the SendMessage method is sent, and then the Onapplicationevent method is executed where it is monitored, and the ShowMessage method in the browser is executed in this method.
Spring integrates DWR comet for no-refresh multiplayer chat room