`
yangxh101
  • 浏览: 1118 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

DWR Server Push(服务器推技术) 实现即时聊天

阅读更多
转:http://rickycm.iteye.com/blog/419380

当你有QQ消息时,QQ的小图标会晃动,我们甚至还可以设定QQ有消息时,自动弹出来!
这些在C/S模式下很容易实现!如果要在B/S模式如何来实现呢?
我们的肯定会想到在客服端调用ajax在后台不断的查询服务器.看是否有关于自己的消息.如果有则查询返回.这种做法肯定会大量的占用系统的资源!不可取!
现在DWR的反转AJAX功能.允许我们从服务器端来控制客服端.而不需要客户端来请求.服务器可以自动把消息发给指定的客户端!

以下DEMO,已经实现了对指定用户发送消息的功能,并且即时显示在指定的用户界面上面.当然你可以修改这些,让它弹出来显示,或者像QQ一样在你页面的某个角落让消息的图标闪动:)
下面我做一个简单的说明:


用户的JAVABEAN User.java
package com.chat;

/**
 * 用户
 * 
 * 
 */
public class User {

 private String userid;

 private String username;

 public String getUserid() {
  return userid;
 }

 public void setUserid(String userid) {
  this.userid = userid;
 }

 public String getUsername() {
  return username;
 }

 public void setUsername(String username) {
  this.username = username;
 }

 public User(String userid, String username) {
  super();
  this.userid = userid;
  this.username = username;
 }

}



聊天处理类 ChatManager.java
package com.chat;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.directwebremoting.ScriptSession;
import org.directwebremoting.ServerContext;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.proxy.dwr.Util;

/**
 * 处理聊天相关
 * 
 * 
 */
public class ChatManager {

 /** 保存当前在线用户列表 */
 public static List<User> users = new ArrayList<User>();

 /**
  * 更新在线用户列表
  * @param username 待添加到列表的用户名
  * @param flag 是添加用户到列表,还是只获得当前列表
  * @param request
  * @return 用户userid
  */
 public String updateUsersList(String username, boolean flag, HttpServletRequest request) {
  User user = null;
  if (flag) { 
   // 这里取会话(HttpSession)的id为用户id 
   user = new User(request.getSession().getId(), username);
   //保存用户到列表
   users.add(user); 
   //将用户id和页面脚本session绑定
   this.setScriptSessionFlag(user.getUserid());
  }
  //获得DWR上下文
  ServletContext sc = request.getSession().getServletContext();
  ServerContext sctx = ServerContextFactory.get(sc);
  //获得当前浏览 index.jsp 页面的所有脚本session
  Collection sessions = sctx.getScriptSessionsByPage("/chat/index.jsp");
  Util util = new Util(sessions);
  //处理这些页面中的一些元素
  util.removeAllOptions("users");
  util.addOptions("users", users, "username");
  util.removeAllOptions("receiver");
  util.addOptions("receiver", users,"userid","username");
  if(!flag){
   return null;
  }
  return user.getUserid();
 }

 /**
  * 将用户id和页面脚本session绑定
  * @param userid
  */
 public void setScriptSessionFlag(String userid) {
  WebContextFactory.get().getScriptSession().setAttribute("userid", userid);
 }

 /**
  * 根据用户id获得指定用户的页面脚本session
  * @param userid
  * @param request
  * @return
  */
 @SuppressWarnings("unchecked")
 public ScriptSession getScriptSession(String userid, HttpServletRequest request) {
  ScriptSession scriptSessions = null;
  Collection<ScriptSession> sessions = new HashSet<ScriptSession>();
  sessions.addAll(ServerContextFactory.get(request.getSession().getServletContext())
    .getScriptSessionsByPage("/chat/index.jsp"));
  for (ScriptSession session : sessions) {
   String xuserid = (String) session.getAttribute("userid");
   if (xuserid != null && xuserid.equals(userid)) {
    scriptSessions = session;
   }
  }
  return scriptSessions;
 }
 
 /**
  * 发送消息
  * @param sender 发送者
  * @param receiverid 接收者id
  * @param msg 消息内容
  * @param request
  */
 public void send(String sender,String receiverid,String msg,HttpServletRequest request){
  ScriptSession session = this.getScriptSession(receiverid, request);
  Util util = new Util(session);
  util.setStyle("showMessage", "display", "");
  util.setValue("sender", sender);
  util.setValue("msg", msg);
 }
}




聊天主页面 index.jsp
<%@ page language="java" pageEncoding="GBK"%>  
<html>  
    <head>  
        <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='dwr/interface/ChatManager.js'></script>  
        <script type='text/javascript' src='dwr/engine.js'></script>  
        <script type='text/javascript' src='dwr/util.js'></script>  
        <script type="text/javascript" src="chat/chat.js"></script>  
    </head>  
    <body>  
        <input type="hidden" name="userid" />  
        <br>  
        昵称:   
        <input type="text" name="username" />  
        <input type="button" value="注册" onclick="register(this);" />  
        <br />  
        <br />  
        我要对   
        <select name="receiver" id="receiver" disabled=true" >  
        </select>  
        说:   
        <input type="text" name="message" id="message" disabled="true" />  
        <input type="button" value="发送" id="send" name="send" disabled="true"  
            onclick="send();" />  
        <br />  
        <br />  
        在线用户列表:   
        <ul id="users">  
        </ul>  
  
        <div id="showMessage" style="display: none">  
            <span id="sender"></span>对你说:   
            <span id="msg"></span>  
        </div>  
    </body>  
</html> 



JAVASCRIPT 文件 chat.js
/**
 * 注册帐号
 */
function register(button) {
 if ($('username').value == "" || $('username').value.length <= 0) {
  alert("请输入昵称");
  return;
 }

 /* 下面是对一些按钮的禁用和激活操作 */
 $('username').disabled = true;
 button.disabled = true;
 $('message').disabled = false;
 $('send').disabled = false;
 $('receiver').disabled = false;

 /* 把我输入的用户名注册到服务器,并获得用户id(这里用session id 代替) */
 ChatManager.updateUsersList($('username').value, true, function(data) {
  if (data != null && data.length > 0) {
   $('userid').value = data; // 注册成功,把userid放到当前页面
  }
 });
}

/**
 * 页面初始化
 */
function init() {
 dwr.engine.setActiveReverseAjax(true); // 激活反转 重要
 ChatManager.updateUsersList(null, false); // 当你打开界面的时候,先获得在线用户列表.
}

/**
 * 发送消息
 */
function send() {
 var sender = dwr.util.getValue('username'); // 获得发送者名字
 var receiver = dwr.util.getValue('receiver'); // 获得接受者id
 var msg = dwr.util.getValue('message'); // 获得消息内容
 ChatManager.send(sender, receiver, msg); // 发送消息
}

window.onload = init;//页面加载完毕后执行初始化方法init




配置文件 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>
 <servlet>
  <servlet-name>dwr-invoker</servlet-name>
  <servlet-class>
   org.directwebremoting.servlet.DwrServlet
  </servlet-class>
  <init-param>
   <description>调试DWR,发布系统时应将其设为false</description>
   <param-name>debug</param-name>
   <param-value>true</param-value>
  </init-param>
  <init-param>
   <description>使用服务器推技术(反转AJAX)</description>
   <param-name>activeReverseAjaxEnabled</param-name>
   <param-value>true</param-value>
  </init-param>
  <init-param>
   <param-name>
    initApplicationScopeCreatorsAtStartup
   </param-name>
   <param-value>true</param-value>
  </init-param>
  <init-param>
   <param-name>maxWaitAfterWrite</param-name>
   <param-value>100</param-value>
  </init-param>
  <load-on-startup>4</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>dwr-invoker</servlet-name>
  <url-pattern>/dwr/*</url-pattern>
 </servlet-mapping>
</web-app>




DWR配置文件 dwr.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">
<dwr>
 <allow>
  <convert converter="bean" match="com.chat.User" />
  <create creator="new" javascript="ChatManager">
   <param name="class" value="com.chat.ChatManager" />
  </create>
 </allow>
</dwr>



分享到:
评论

相关推荐

    dwr实现的网页即时聊天

    在这个"使用dwr实现的网页即时聊天"项目中,我们将深入探讨如何利用DWR的服务器推技术来创建一个实时的群聊系统。 1. **DWR框架**: DWR简化了JavaScript与Java之间的通信,通过在浏览器端提供动态生成的JavaScript ...

    服务器推--DWR中的push机制-Reverse_Ajax.docx

    【服务器推技术与DWR中的push机制】 在Web开发中,传统的Ajax技术主要是基于“拉”(Pull)模型,即浏览器(Browser)发起请求,服务器(Server)被动响应。然而,这种模型无法满足实时性需求,例如股票行情、即时...

    serverpush聊天室

    "ServerPush聊天室"是一种基于DWR(Direct Web Remoting)技术实现的实时通信系统,主要特点是能够实现实时的点对点聊天功能。在这个系统中,服务器主动将信息推送至客户端,而不是传统的客户端发起请求获取数据的...

    dwr实现前台监控 后台推送即时信息

    DWR Push基于Comet技术,可以实现在服务器有新数据时主动推送给客户端。首先,你需要在服务器端创建一个Push服务,比如`NotificationPusher`类,里面有一个`broadcastMessage`方法用于广播消息。然后,在客户端,你...

    DWR 在线即时聊天系统,实现了对指定用户发送消息,和即时显示功能

    我不能把公司的代码贴出来,所以我自己写了一个DEMO,已经实现了对指定用户发送消息的功能,并且即时显示在指定的用户界面上面.当然你可以修改这些,让它弹出来显示,或者像QQ一样在你页面的某个角落让消息的图标闪动:)

    dwr 反推技术

    1. **实时消息传递**:用户发送的消息可以通过DWR直接传递到服务器,服务器处理后立即通过反推技术推送给所有在线的接收者,无需每个接收者都轮询服务器以获取最新消息。 2. **高效数据传输**:DWR支持JSON和其他轻...

    SD大会精品讲座:利用AJAX/Java 技术建立高流量的即时双向沟通网站

    - **Comet**:一种实现Server Push的技术,通过对HTTP连接的长期保持来实现服务器向客户端推送数据。 - **WebSocket**:提供了全双工的通信通道,可以实现客户端和服务器之间的双向通信。 #### 六、应用实例 - ...

    AJAX项目开发指南

    - **即时网页聊天**:通过Server Push技术,实现消息的实时推送。 ##### 3.3 具体实现技术 - **AJAX网络访问技术**: - XMLHttpRequest (XHR):用于发起异步HTTP请求。 - `&lt;iframe&gt;`:通过内嵌框架实现跨域数据...

    jsp知识积累

    结合DWR(Direct Web Remoting)技术,可实现可编辑下拉菜单,允许用户即时修改选项。这种设计通常涉及数据库查询,以动态填充下拉列表,并允许用户自定义选择。 #### 日期比较 在JSP中,比较两个日期的大小可以...

Global site tag (gtag.js) - Google Analytics