一、实现原理剖析:
1.在群聊中,我们知道如何通过uri获得所有的session集合,但在单对单的聊天中并不需要获取全部,他只需要在彼此的session中进行聊天的管理/展示。
2.为此我们通过构造Map集合,通过单独唯一的key(用户名或者id编号,唯一即可),并同时将当前的session,put进去便可。当我们要指定发送对象时,我们便可获取
被发送对象的session,构建util。调用客户端编写好的js响应方法,产生相应的气泡提示了。
流程:Map构建-》发送消息给指定对象-》通过Map来get对象的session-》通过session构建utli-》util对客户端的js进行调用
ps:前提我们知道dwr中的远程调用Java类是单例模式下的。否则根本无法保存每一个session。
二、实现核心代码:
1.远程调用类:
- public class MsgPushService {
- public static Map<String,Object> sessionManager = new HashMap<String,Object>();
- /**
- * 添加客户端session ps:firfox有错误提示..-已解决,将跳转放置dwr的回调函数中
- * 1.登录成功后进行调用
- * @param username
- */
- public String addScriptSession(String username,HttpServletRequest req) {
- if(!"".equals(username)&&username!=null){
- sessionManager.put(username,WebContextFactory.get().getScriptSession());
- }
- return "ok";
- }
- public ScriptSession getScriptSession(String username) {
- return (ScriptSession) sessionManager.get(username);
- }
- /**
- * 2.发送消息时进行调用
- * @param senderName
- * @param receiverName
- * @param title
- * @param content
- * @return
- */
- @SuppressWarnings("unchecked")
- public String pushMsg(String senderName,String receiverName,String title,String content,HttpServletRequest req) {
- ScriptSession receiver_session = this.getScriptSession(receiverName);
- Collection<ScriptSession> cols = new ArrayList<ScriptSession>();
- cols.add(receiver_session);
- Util util = new Util(cols);
- util.addFunctionCall("doReply","ok");
- return "ok";
- }
- /**
- *
- * 这里暂时没有用到:给所有客户端页面添加脚本
- * @param function
- * @param msg
- * @param req
- * @return
- */
- @SuppressWarnings("unchecked")
- public String addFunctionCallOnAllScriptSession(final String function,final String msg,HttpServletRequest req) {
- ServletContext sc = req.getSession().getServletContext();
- ServerContext sctx = ServerContextFactory.get(sc);
- Collection<ScriptSession> sessions = sctx
- .getScriptSessionsByPage("/msgpush/jsp/msgPush.do");
- Util util = new Util(sessions);
- util.addFunctionCall(function,msg);
- return "ok";
- }
- }
2.页面调用:
- <%@ page language="java" contentType="text/html; charset=utf-8"
- pageEncoding="utf-8"%>
- <%@taglib uri="/struts-tags" prefix="s"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <Meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>欢迎 ${sessionScope.user.username }</title>
- <link rel="stylesheet" href="../js/poshytip-1.1/tip-darkgray/tip-darkgray.css" type="text/css" />
- <script type='text/javascript' src='../dwr/engine.js'> </script>
- <script type='text/javascript' src='../dwr/interface/MsgPushService.js'> </script>
- <script type='text/javascript' src='../dwr/util.js'> </script>
- <script type="text/javascript" src="../js/jquery.js"></script>
- <script type="text/javascript" src="../js/msgpush.js"></script>
- <script type="text/javascript" src="../js/poshytip-1.1/jquery.poshytip.js"></script>
- </head>
- <body>
- <a id="notice" title="">消息通知中心</a>
- <a href="sessionMgmt.do?pageIndex=0" onclick="hide();" target="_blank">会话管理中心</a>
- <hr>
- 在线用户列表:
- <s:iterator value="#application.OnlineUsers" id="user">
- <span id="<s:property value='#user' />">
- <input type="radio" name="rusers" value="<s:property value='#user' />"/>
- <s:property value='#user' />
- </span>
- </s:iterator>
- <s:if test="#application.OnlineUsers.size==1">
- 暂没有可发送消息的对象
- </s:if>
- <hr>
- <form>
- <table>
- <tr>
- <td>消息内容:</td>
- <td>
- <input type="text" id="title"/>
- </td>
- </tr>
- <!--
- <tr>
- <td>内容</td>
- <td>
- <textarea rows="3" cols="20" id="content" ></textarea>
- </td>
- </tr>
- -->
- <tr>
- <td></td>
- <td>
- <input type="button" value="发送" onclick="javascript:pushMsg();"/>
- <input type="reset" value="清空"/>
- </td>
- </tr>
- </table>
- </form>
- <input type="hidden" value="${sessionScope.user.username }" id="username"/>
- </body>
- </html>
3.脚本处理
- $(function(){
- //在线用户列表中过滤本身
- var id="#"+$("#username").val();
- $(id).css("display","none");
- });
- function pushMsg(){
- var title=$("#title").val();
- //var content=$("#content").val();
- var receiverName=$(":radio:checked").val();
- if (receiverName == undefined) {
- alert("请选择发送的对象");
- return;
- }
- if (title == "" || title.length <= 0) {
- alert("请输入主题");
- return;
- }
- /*
- if (content == "" || content.length <= 0) {
- alert("请输入内容");
- return;
- }
- */
- /*
- MsgPushService.send($("#username").val(),$(":radio:checked").val(),$("#title").val(),$("#content").val(),{
- //指定回调函数
- callback:getMsg,//指定超时时长
- timeout:1000,//指定错误处理函数
- errorHandler:function(message) { alert("错误提示: " + message); },//指定
- warningHandler:function(message) { alert("Oops: " + message); },textHtmlHandler: function(message) { alert("Oops: " + message); },exceptionHandler: function(message) { alert("Oops: " + message); },//指定发送请求的方式
- httpMethod:'POST',async:true,//指定发送请求之前的勾子函数
- preHook:function(){
- //alert('远程调用之前...')
- },//指定发送请求之后的勾子函数
- postHook:function(){
- //alert('远程调用之后...')
- }
- });
- */
- MsgPushService.pushMsg($("#username").val(),receiverName,title,"",function(msg){
- //alert(msg);
- });
- //MsgPushService.test();
- }
- function getMsg(msg){
- //alert(msg);
- }
- function doReply(msg){
- if('ok'==msg){
- $('#notice').poshytip({
- className: 'tip-darkgray',showOn:'none',//一直显示
- content:'你有新消息 <a href="sessionMgmt.do?pageIndex=0" onclick="hide();" target="_blank">查看留言</a>',alignTo:'target',//定位的相对目标
- alignX:'right',alignY:'center',offsetX:5
- });
- $('#notice').poshytip('show');
- }
- }
- function hide(){
- $('#notice').poshytip('hide');
- }
- /**
- * 页面初始化
- */
- function init() {
- dwr.engine.setActiveReverseAjax(true); // 激活反转 重要
- MsgPushService.addScriptSession($("#username").val(),function(msg){});
- }
- window.onload = init;//页面加载完毕后执行初始化方法init
效果图: