【叨、校长】一个基于Extjs、Pushlet美轮美奂的Web聊天室

本实例基于pushlet官方实例。通俗易懂、老少皆宜! --叨、校长

下面给出核心代码、代码都有注释、希望可以给大家带来帮助!

【叨、校长】一个基于Extjs、Pushlet美轮美奂的Web聊天室_第1张图片

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'))+" &#160 进入了聊天室!</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)+" &#160 离开了聊天室!</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;
	}
	
}
 

 

你可能感兴趣的:(JavaScript,html,css,ExtJs,Pushlet)