最近开始学习dwr,学习的过程中也遇到了诸多的麻烦。现在将问题以及经验小小的总结一下。由于本人只是一个大学还没毕业的小白。如果有错误还请见谅。
用dwr做了一个精准消息推送的Demo。
项目的基本结构。只是一个小demo,也就没那么复杂。
配置文件不在赘述。直接上code。
<script type="text/javascript" src="./dwr/engine.js"></script>
<script type="text/javascript" src="./dwr/util.js"></script>
<script type="text/javascript" src="./dwr/interface/Message.js"></script>
<script type="text/javascript" src="js/jquery-2.0.2.js"></script>
<script type="text/javascript">
var chatlog = "";
function sendMessage() {
var message = $("#message").val();
var user = $("#user").val();
// 通过代理调用后台的addMessage方法发送消息
Message.addMessage(user, message);
}
// 前台接受消息的方法,由后台调用
function receiveMessages(messages) {
var lastMessage = messages;
chatlog = "<p>" + lastMessage + "</p>" + chatlog;
$("#list").html(chatlog);
}
//读取name值作为推送的唯一标示
function onPageLoad() {
// 获取URL中的name属性为唯一标识符
var userId = getQueryString("name");
$("#myName").html(userId);
// 通过代理,传入区别本页面的唯一标识符
Message.onPageLoad(userId);
}
//获取url中的参数
function getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null)
return unescape(r[2]);
return null;
}
$(document).ready(function() {
dwr.engine.setActiveReverseAjax(true);// 开启逆向Ajax,也可写在body标签的onload方法中
dwr.engine.setNotifyServerOnPageUnload(true);
onPageLoad();
});
</script>
</head>
<body>
My name is:
<span id="myName" style="color: red"></span>
<br /> To:
<br />
<input id="user" type="text" />
<br /> input message:
<br />
<input id="message" type="text" value="hey" />
<input type="button" value="send" onclick="sendMessage()" />
<br>
<div id="list"></div>
</body>
我们可以在页面的输入index.jsp?name=XX来设置当前对象。其中一些简单JavaScript是用jQuery实现的。我的jQuery也不大好,先练练。
这是后台java源码:
public class Message {
// 载入页面时调用,传入name值作为推送的标识
public void onPageLoad(String name) {
ScriptSession session = WebContextFactory.get().getScriptSession();
session.setAttribute("name", name);
}
public void addMessage(String userid, String message) {
final String userId = userid;
final String autoMessage = message;
ScriptSession session = WebContextFactory.get().getScriptSession();
final String from = session.getAttribute("name").toString();
System.out.println("From: " + from + ", To: " + userid + ", Msg: "
+ message);
// 通过ScriptSessionFilter筛选符合条件的ScriptSession
Browser.withAllSessionsFiltered(new ScriptSessionFilter() {
// 实现match方法,条件为真为筛选出来的session
public boolean match(ScriptSession session) {
String name = session.getAttribute("name").toString();
return name == null ? false : userId.equals(name);
}
}, new Runnable() {
private ScriptBuffer script = new ScriptBuffer();
public void run() {
// 设定前台接受消息的方法和参数
script.appendCall("receiveMessages", autoMessage);
Collection<ScriptSession> sessions = Browser
.getTargetSessions();
// 向所有符合条件的页面推送消息
for (ScriptSession scriptSession : sessions) {
if (scriptSession.getAttribute("name").equals(userId)) {
scriptSession.addScript(script);
}
}
}
});
}
}
可以看到,通过WebContextFactory.get().getScriptSession()这个方法来获取前台上下文本信息。这里将获取到的信息放在session里,session在将name字段保存并在下文进行验证来识别用户。
在主代码中用到了一个ScriptSessionFilter,这是用来过滤用户的,筛选符合条件的session。特地查了一下ScriptSessionFilter,发现里面主要实现了一个match方法:
public boolean match(ScriptSession session) {
String name = session.getAttribute("name").toString();
return name == null ? false : userId.equals(name);
}
上面部分主要用来进行筛选的。
}, new Runnable() {
private ScriptBuffer script = new ScriptBuffer();
public void run() {
// 设定前台接受消息的方法和参数
script.appendCall("receiveMessages", autoMessage);
Collection<ScriptSession> sessions = Browser
.getTargetSessions();
// 向所有符合条件的页面推送消息
for (ScriptSession scriptSession : sessions) {
if (scriptSession.getAttribute("name").equals(userId)) {
scriptSession.addScript(script);
}
}
}
});
这个部分主要用来设定向前台推送消息的。
整个代码主要用到的API:ScriptSession,WebContextFactory,ScriptSessionFilter,ScriptBuffer。总结一下,然后在查询这几个API具体实现的源码。
好好学习,天天向上。