本实例基于pushlet官方实例。通俗易懂、老少皆宜! --叨、校长
下面给出核心代码、代码都有注释、希望可以给大家带来帮助!
Pushlet原理:
Pushlet基于HTTP流,这种技术常常用在多媒体视频、通讯应用中,比如QuickTime。与装载HTTP页面之后马上关闭HTTP连接的做法相反,Pushlet采用HTTP流方式将新变动的数据主动地推送到client(客户端),再此期间HTTP连接一直保持打开
客户端代码:
function initChatRoom(themes){ var SUB_LOGIN="/Chat/Login"; //登录 var SUB_MESSAGE="/Chat/Message"; //发送消息 var SUB_LEAVE="/Chat/Leave"; //离开 // 表情数组 var array=[ ["am","aq","aw","ax","biz","bs","bz","cd","cf"], ["db","dk","dy","fad","fd","fw","hh","hq","hx"], ["je","jk","jy","ka","kf","kkl","kl","kq","kt"], ["ku","lh","ll","lq","luo","mr","ng","no","ok"], ["ot","pp","pq","ps","qd","qi","qq","qt","tw"] ] var win=initLoginWin(); win.show(); Ext.getCmp("user_name_txtfield").focus(); /** * 登录界面 * @return {} */ function initLoginWin(){ var win=new Ext.Window({ title:"请登录...", width:204, height:120, layout:"form", labelWidth:40, labelAlign:"right", defaultType:"textfield", items:[{ fieldLabel:"昵称", id:"user_name_txtfield", listeners:{ specialkey : function(field, e) { if (e.getKey() == Ext.EventObject.ENTER) { var user=win.getComponent(0).getValue(); var user_name=encodeURIComponent(encodeURIComponent(user)); if(user_name.length!=0){ win.close(); var chat=createChatRoom(user); chat.show(); var msg_panel=chat.getComponent(0); var tree=chat.getComponent(2); initPushLet(user_name,msg_panel,tree); }else{ Ext.Msg.alert("提示","请输入用户名..."); return } } } } },{ fieldLabel:"口令" }], buttonAlgin:"right", buttons:[{ text:"登录", handler:function(){ var user=win.getComponent(0).getValue(); var user_name=encodeURIComponent(encodeURIComponent(user)); if(user_name.length!=0){ win.close(); var chat=createChatRoom(user); chat.show(); var msg_panel=chat.getComponent(0); var tree=chat.getComponent(2); initPushLet(user_name,msg_panel,tree); }else{ Ext.Msg.alert("提示","请输入用户名..."); return } } },{ text:"取消", handler:function(){ win.close(); } }] }) return win; } /** * 聊天面板 * @param {} user_name 用户名 * @return {} */ function createChatRoom(user_name){ var msgPanel=createCenterPanel(); var onlinePanel=createEastPanel(); var inputPanel=createSouthPanel(); var win=new Ext.Window({ title:"校长聊天室", width:592, height:511, layout:"border", tools:[{ id:"minimize", handler:function(){ win.setPagePosition(0,document.body.clientHeight-26); win.setSize(160,0); win.getTool("restore").setVisible(true); win.getTool("minimize").setVisible(false); } },{ id:"maximize", handler:function(){ // var w=document.body.clientWidth-40; // var h=document.body.clientHeight-40; // win.maximize(); win.setPagePosition(5,5); win.setSize(document.body.clientWidth-10,document.body.clientHeight-10); win.getTool("restore").setVisible(true); win.getTool("minimize").setVisible(true); win.getTool("maximize").setVisible(false); } },{ id:"restore", hidden:true, handler:function(){ //win.restore(); win.setPagePosition((document.body.clientWidth-592)/2,(document.body.clientHeight-511)/2); win.setSize(592,511); win.getTool("restore").setVisible(false); win.getTool("maximize").setVisible(true); win.getTool("minimize").setVisible(true); } },{ id:"down", handler:function(e){ var menu = new Ext.menu.Menu([{ text:"火红烈焰", iconCls:"theme_red", handler:function(){ document.getElementsByTagName("link")[1].href="ext3.2/resources/css/"+themes[0]; } },{ text:"绿色心情", iconCls:"theme_olive", handler:function(){ document.getElementsByTagName("link")[1].href="ext3.2/resources/css/"+themes[1]; } },{ text:"午夜迷情", iconCls:"theme_dark", handler:function(){ document.getElementsByTagName("link")[1].href="ext3.2/resources/css/"+themes[2]; } },{ text:"白色恋人", iconCls:"theme_gray", handler:function(){ document.getElementsByTagName("link")[1].href="ext3.2/resources/css/"+themes[3]; } },{ text:"紫色魅影", iconCls:"theme_purple", handler:function(){ document.getElementsByTagName("link")[1].href="ext3.2/resources/css/"+themes[4]; } },{ text:"咖啡物语", iconCls:"theme_coffee", handler:function(){ document.getElementsByTagName("link")[1].href="ext3.2/resources/css/"+themes[5]; } }]) menu.showAt(e.getPoint()); } }], items:[msgPanel,inputPanel,onlinePanel], listeners:{ close:function(){ var win=initLoginWin(); win.show(); //用户退出、发送离开主题 PL.publish(SUB_LEAVE,"username="+name+"&userid="+PL.sessionId+"&lflag=1"); //PL.leave(); } } }).show(); function createCenterPanel(){ var panel=new Ext.Panel({ region:"center", id:"message_panel", bodyStyle:"margin:0 10px 10px 0;", autoScroll:true }) return panel; }; function createEastPanel(){ var panel=new Ext.tree.TreePanel({ title:"在线用户", region:"east", width:140, bodyStyle:"margin:0 0 10px 10px;", root:new Ext.tree.TreeNode({ text:"在线用户" }), rootVisible: false }) return panel; }; function createSouthPanel(){ var panel=new Ext.Panel({ region:"south", height:147, layout:"fit", tbar:[{ iconCls:"icon_font", text:"", handler:function(){ var html=createFaceGrid(user_name); var win=new Ext.Window({ width:250, height:160, id:"face_win", html:html }).show(); } },'-',{ iconCls:"icon_face", xtype:"button", handler:function(e){ //alert(sadsad); var html=createFaceGrid(user_name); var t=Number(e.el.getXY()[0]-135); var l=Number(e.el.getXY()[1]+20); $("#details").css({ "top" :t, "left" :l }).fadeIn("fast"); $("#details").html(html); } }], items:[{ xtype: 'textarea', id:"my_message", enableKeyEvents:true, listeners:{ keypress: function(f,e) { if (e.getKey() == e.ENTER) { var msg_text=Ext.getCmp("my_message").getValue(); var msg=encodeURIComponent(encodeURIComponent(msg_text)); PL.publish(SUB_MESSAGE,"username="+encodeURIComponent(encodeURIComponent(user_name))+"&userid="+PL.sessionId+"&msg="+msg); sendMsg(user_name,msg_text,msgPanel); Ext.getCmp("my_message").setValue(""); Ext.getCmp("my_message").focus(); } } } }], buttons:[{ text:"发送", handler:function(){ var msg_text=Ext.getCmp("my_message").getValue(); var msg=encodeURIComponent(encodeURIComponent(msg_text)); //发送小心的主题、注意转码 PL.publish(SUB_MESSAGE,"username="+encodeURIComponent(encodeURIComponent(user_name))+"&userid="+PL.sessionId+"&msg="+msg); sendMsg(user_name,msg_text,msgPanel); Ext.getCmp("my_message").setValue(""); } },{ text:"重置" }] }) return panel; }; return win; }; /** * 初始化Pushlet 不断的发送请求、保持链接 * @param {} name * @param {} panel * @param {} tree */ function initPushLet(name,panel,tree){ var subListener=SUB_LOGIN+","+SUB_MESSAGE+","+SUB_LEAVE; PL.joinListen(subListener); PL.publish(SUB_LOGIN,"username="+name+"&userid="+PL.sessionId); /** * 每隔三秒连接一次 * @param {} event */ PL.onEvent = function(event){ if(event){ if(event.get('userid')!=PL.sessionId){ //如果获取到登录主题、则发送登录消息到每个连接 if(event.getSubject()==SUB_LOGIN){ if(event.get("username")){ var flag=true; var nodes=tree.getRootNode().childNodes; if(tree.getNodeById(event.get('userid'))){ }else{ var node=new Ext.tree.TreeNode({ text:decodeURIComponent(event.get('username')), id:event.get('userid'), iconCls:"node_icon", leaf:true }) tree.getRootNode().appendChild(node); var html = "<div style='margin : 15px;color:#999;'>"+decodeURIComponent(event.get('username'))+"   进入了聊天室!</div>"; panel.body.insertHtml("afterBegin",html); } } } //如果获取到发送消息主题、则发送登录消息到每个消息框、自己不发送 if(event.getSubject()==SUB_MESSAGE){ var msg = event.get('msg'); if(msg){ var datetime = event.get('datetime') || new Date().format('Y-m-d H:i:s'); var name = event.get('username'); reciveMsg(name,msg,panel); } } //用户离开 if(event.getSubject()==SUB_LEAVE){ if(event.get('lflag')){ var name = event.get('username'); var id=event.get('userid'); var html = "<div style='margin : 15px;color:#999;'>"+decodeURIComponent(name)+"   离开了聊天室!</div>"; tree.getNodeById(id).remove(true); panel.body.insertHtml("afterBegin",html); } } } } } window.onRefreshAck=function(event){ if(event.getSubject()!=SUB_LOGIN){ PL.publish(SUB_LOGIN,"username="+name+"&userid="+PL.sessionId); } } } //表情面板 function createFaceGrid(name){ var html="<table>"; for(var i=0;i<array.length;i++){ html+="<tr>"; for(var j=0;j<9;j++){ var img="images/face/"+array[i][j]+".gif"; html+="<td id='"+array[i][j]+"&"+name+"' onclick='chooseFace(this);'><img src="+img+"></td>"; } html+="</tr>"; } html+="</table>"; return html; } } //选择表情 function chooseFace(_this){ var face=_this.id.split("&")[0]; var user_name=_this.id.split("&")[1]; var html="<img src='images/face/"+face+".gif'/>"; var msg=html; var msg_txt=encodeURIComponent(encodeURIComponent(html)); PL.publish("/Chat/Message","username="+encodeURIComponent(encodeURIComponent(user_name))+"&userid="+PL.sessionId+"&msg="+msg); sendMsg(user_name,msg,Ext.getCmp("message_panel")); $("#details").hide(); } //发送消息 function sendMsg(name,msg,panel){ var html="<div style='margin : 15px;'>"+name+"("+new Date().format('Y-m-d H:i:s')+")<br>"+msg+"<div>"; panel.body.insertHtml("afterBegin",html); } //接收消息 function reciveMsg(name,msg,panel){ var html="<div style='margin : 15px;'>"+decodeURIComponent(name)+"("+new Date().format('Y-m-d H:i:s')+")<br>"+decodeURIComponent(msg)+"<div>"; panel.body.insertHtml("afterBegin",html); }
后台服务代码
public class ChatService extends EventPullSource{ //这是发送消息的后台服务、每3秒推送一次 public final String SUBJECT="/Chat/Message"; protected long getSleepTime() { return 3000; } protected Event pullEvent() { Event event = Event.createDataEvent(SUBJECT); return event; } }