初学dwr推技术(总结一下)

下面是我在网上看过的两个小实例

[color=red][b]第一个:[/b][/color]
DWR2.0.x的推技术以推发送消息,适用于ChatRoom,股票信息显示等场景,优于现在JS定时轮询服务端的策略,大大节省服务端的资源(数据无变化时不需要应答客户端的定时查询)。

推技术的经典范例是DWR Examples里的ChatRoom。

推消息的接收页

1. 引入dwr及那个负责执行推操作的Java类(NoticeService)的js


<script type="text/javascript" src="dwr/interface/NoticeService.js"></script>
<script type="text/javascript" src="dwr/engine.js"></script>
<script type="text/javascript" src="dwr/util.js"></script>

2.设定任意的接收推信息的js函数

function receiveMessages(message) {
$('result').innerHTML += "收到消息:" + message + "
";
}

3.在body的onload里设定ReverseAjax=true

<body onload="DWREngine.setActiveReverseAjax(true);">

负责推送消息的Java类

public class NoticeService {
public void send(String message) {
WebContext wctx = WebContextFactory.get();
ScriptBuffer script = new ScriptBuffer();
script.appendScript("receiveMessages('").appendData(message).appendScript("');");

ServerContext sctx = ServerContextFactory.get(wctx
.getServletContext());

Collection<ScriptSession> pages =
sctx.getScriptSessionsByPage("/ajax/dwr-push.html");

for (ScriptSession session : pages) {
session.addScript(script);
}

/*
Collection<ScriptSession> pages =
sctx.getScriptSessionsByPage("/ajax/dwr-push.html");
for (ScriptSession session : pages) {
session.addScript(script);
}
这里是获取所有/ajax/dwr-push.html页面的ScriptSession
返回一个ScriptSession类型的Collection集合
遍历得到所有ScriptSession的实例对象向所有页面发送内容

如果你执行对当前页面发送内容 可以直接写:
ScriptSession session = wctx.getScriptSession();
session.addScript(script);
*/

}
}

可见,用ScriptBuffer构造一段在客户端执行的JavaScript,然后使用WebContext,ServerContext定位需要发送的session进行发送。注意这里HardCode了URL路径来确定Subscriber,也可以像ChatRoom里面那样,用currenpage发给与NoticeService的调用者发起者在同一页的session。
[b]原文地址:[url]http://www.family168.com/oa/tech/ajax.html[/url][/b]


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

[i]用户的JAVABEAN User.java [/i]

package com.lhq;

/**
* 用户类
*
* @author 廖瀚卿
*
*/
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;
}

}


[b]聊天处理类 ChatManager.java[/b]

package com.lhq;

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;

/**
* 处理聊天相关
*
* @author 廖瀚卿
*
*/
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);
}
}

[b]聊天主页面 index.jsp (这个有的用户用$()标记得不到值,在页面表单加上ID同名属性或者用getelementbyid)[/b]

<%@ 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='/chat/dwr/interface/ChatManager.js'></script>
<script type='text/javascript' src='/chat/dwr/engine.js'></script>
<script type='text/javascript' src='/chat/dwr/util.js'></script>

<script type="text/javascript" src="/chat/js/chat.js"></script>
</head>
<body>
<input type="hidden" name="userid" id="userid" />
<br>
昵称:
<input type="text" name="username" id="username" />
<input type="button" value="注册" onclick="register(this);" />
我要对
<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();" />
在线用户列表:
<ul id="users">
</ul>

<div id="showMessage" style="display: none">
<span id="sender"></span>对你说:
<span id="msg"></span>
</div>
</body>
</html>



[b]JAVASCRIPT 文件 chat.js[/b]

/**
* 注册帐号
*/
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


[b]配置文件 web.xml [/b]

<?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>

[b]DWR配置文件 dwr.xml[/b]

<?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.lhq.User"/>
<create creator="new" javascript="ChatManager">
<param name="class" value="com.lhq.ChatManager"/>
</create>
</allow>
</dwr>



[b]原文地址:[url]http://yourgame.iteye.com/blog/199079[/url][/b]

以上例子所需jar包:commons-logging-1.1.1.jar 和 dwr.jar

[b]关于ScriptSession的一些介绍

可以参考文章 地址:[/b][url]http://1632004.blog.163.com/blog/static/299914972010350858396/[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值