<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
<init-param>
<!--
Ajax important , charset=utf-8
其他都为gbk
-->
<param-name>ignore</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<listener>
<listener-class>hyjc.listener.CustomSessionListener</listener-class>
</listener>
还是利用了 poll 的 方案 ,定时 刷新信息, 下一步打算利用长连接 来试试
生成了一个 Ext.window 就是聊天窗口了

Ext.onReady(function() {
var chatWin = new Ext.Window({
width:800,
height:500,
title:'Ext聊天窗口测试版',
renderTo:document.body,
border :false,
hidden :true,
layout:'border',
closeAction :'hide',
collapsible :true,
constrain :true,
iconCls :'my-userCommentIcon',
maximizable :true,
items:[
{
region:'west',
id:'chat-west-panel',
title:'用户面板',
split:true,
width: 170,
minSize: 100,
maxSize: 200,
collapsible: true,
constrain :true,
//margins:'0 0 0 5',
layout:'accordion',
layoutConfig:{
animate:true
},
items: [{
items:
new Ext.tree.TreePanel({
id:'im-tree',
rootVisible:false,
lines:false,
border :false,
dataUrl: 'chat/updateChat.jsp',
singleExpand :true,
selModel:new Ext.tree.MultiSelectionModel(),
root: new Ext.tree.AsyncTreeNode({
text:'Online',
children:[{
text:'Sunrise',
id:'SunriseIm',
nodeType: 'async',
singleClickExpand :true,
expandable:true,
expanded:true
}]
})
})
,
title:'在线人员',
//layout:'form',
border:false,
autoScroll:true,
iconCls:'im_list',
tools:[{
id:'refresh',
qtip: '刷新在线信息',
// hidden:true,
handler: function(event, toolEl, panel) {
reloadUser();
}
},
{
id:'close',
qtip: '清除选定',
// hidden:true,
handler: function(event, toolEl, panel) {
Ext.getCmp('im-tree').getSelectionModel().clearSelections();
}
}
]
},{
title:'Settings',
html:'<p>Some settings in here.</p>',
border:false,
iconCls:'settings'
}]
},
{
region:'center',
layout:'border', items:[
{
region:'center',
title:'历史记录 ',
id:'history_panel',
autoScroll:true,
iconCls :'my-userCommentIcon',
tools:[{
id:'refresh',
qtip: '注意:如果长时间没有收到对方回应,试一下',
// hidden:true,
handler: function(event, toolEl, panel) {
// refresh logic
}
}]
},
{
region:'south',
title:'聊天啦',
layout:'fit',
iconCls :'user_edit',
autoScroll:true,
height: 200,
collapsible: true,
//margins:'0 0 0 0',
items:{
xtype:'form',
baseCls: 'x-plain',
autoHeight:true,
autoWidth:true,
bodyStyle: 'padding:10 10px 0;',
defaults: {
anchor: '95%'
},
items:[
{
xtype:'htmleditor',
height:130,
id:'htmleditor',
hideLabel :true
}
]
}
,bbar :[{
text:'发送请输入Ctrl-Enter',
handler:function() {
sendmsg();
},
iconCls:'my-sendingIcon'
}
,'-',{
text:'清除',
handler:function() {
Ext.getCmp("htmleditor").reset();
}
}
]
}
]
}
]
});
var query = location.search.substring(1);//获取查询串
var sessionId = SESSION;//Ext.urlDecode(query).sid;
// 发送消息
function sendmsg() {
Ext.getCmp("htmleditor").syncValue();
var content_value = Ext.getCmp("htmleditor").getValue();
if (content_value.trim() == '') {
alert("您没有输入消息文本内容!");
Ext.getCmp("htmleditor").focus(true);
return;
}
var receivers_values = [];
var tree = Ext.getCmp('im-tree');
var receivers = tree.getSelectionModel().getSelectedNodes();
for (i = 0; i < receivers.length; ++i) {
receivers_values.push(receivers[i].attributes.sessionId);
}
if (receivers_values.length == 0) {
alert("您没有选择接收者!");
tree.focus();
return;
}
//alert(receivers_values.length);
if (receivers_values.length > 1) {
if (!confirm("您选择了多个接收者,是否继续?")) {
return;
}
}
var nickname_value = 'forget';
var pars = {
"content":content_value,
"receivers":"" + receivers_values,
"sender":sessionId
// "nickname":'forget'
};
var conn = new Ext.data.Connection();
// 发送异步请求
conn.request({
// 请求地址
url: 'chat/sendmsg.jsp',
method: 'post',
params: pars,
// 指定回调函数
callback: msgsent
});
}
function msgsent(options, success, response) {
requestCount--;
if (success) {
try {
var jsonObj = Ext.util.JSON.decode(response.responseText);
} catch(e) {
}
if (jsonObj && jsonObj.success)
{
var cur = jsonObj.cur;
var sessions = [];
var c = node.childNodes;
for (var i = 0; i < c.length; i++) {
sessions[c[i].attributes.sessionId] = c[i].attributes;
}
if (cur) {
var a = [];
for (var j = 0; j < cur.receivers.length; j++) {
a.push(sessions[cur.receivers[j]].loginName);
}
var msg = '<div style="margin:20px 5px 10px 5px"> <img src="js/ext/user_comment.png"/> {0} <b>{1}</b> 对 <b>{2}</b> 说:<br> </div>' ;
var chat_record =new Ext.Element(document.createElement('div'));
chat_record.addClass('chat_record');
chat_record.update('<span style="margin:0px 5px 0px 5px">'+cur.content+'</span>');
Ext.getCmp("history_panel").body.appendChild(chat_record);
var canvas=new Ext.Element(document.createElement('canvas'));
var size_chat=chat_record.getSize();
if(!Ext.isIE && size_chat.height < 100) {
chat_record.setHeight(100);
size_chat.height=100;
}
canvas.setSize(size_chat.width-30,size_chat.height);
//canvas.setSize(size_chat.width-,40);
chat_record.appendChild(canvas);
if(window['G_vmlCanvasManager'] ) {
G_vmlCanvasManager.initElement(canvas.dom);
}
draw_m(chat_record.dom.lastChild,'#FFB100');
var mc = String.format(msg, cur.time, sessions[cur.sender].loginName, a);
Ext.getCmp("history_panel").body.insertHtml('beforeEnd',
mc);
Ext.getCmp("history_panel").body.scroll('b', 10000, {
duration:0.1
});
}
Ext.getCmp("htmleditor").reset();
}
else if(response.result)
alert(response.result);
} else {
if(response.responseText)
alert(response.responseText);
}
}
//event for source editing mode
new Ext.KeyMap(Ext.getCmp("htmleditor").getEl(), [
{
key: 13,
ctrl:true,
stopEvent :true,
fn: sendmsg
}
]);
//event for normal mode
Ext.getCmp("htmleditor").onEditorEvent = function(e) {
this.updateToolbar();
var keyCode = (document.layers) ? keyStroke.which : e.keyCode;
if (keyCode == 13 && e.ctrlKey) sendmsg(); //it'a my handler
}
var tree = Ext.getCmp('im-tree');
var node = tree.getNodeById('SunriseIm');
var requestCount = 0;
function reloadUser() {
if (requestCount == 10) {
alert('服务器连接失败');
window.location = 'login.jsp';
return;
}
requestCount++;
var conn = new Ext.data.Connection();
// 发送异步请求
conn.request({
// 请求地址
url: 'chat/updateChat.jsp',
method: 'post',
// 指定回调函数
callback: callback
});
//回调函数
function callback(options, success, response) {
requestCount--;
if (success) {
try {
var jsonObj = Ext.util.JSON.decode(response.responseText);
} catch(e) {
}
if (jsonObj)
{
var jsonNodes = jsonObj.nodes;
var msgs = jsonObj.msgs;
var cs = node.childNodes ;
var nodes = {};
var sessions = {};
for (var i = 0; i < cs.length; i++) {
nodes[cs[i].id] = cs[i];
}
var user;
for (var i = 0; i < jsonNodes.length; i++) {
user = jsonNodes[i];
// alert(user.sessionId);
sessions[user.sessionId] = user;
if (nodes[user.id]) {
nodes[user.id] = null;
continue;
}
node.appendChild(user);
}
for (var id in nodes) {
if (nodes[id])
node.removeChild(nodes[id]);
}
var msg = '<div style="margin:20px 5px 10px 5px"> <img src="js/ext/user_comment.png"/> {0} <b>{1}</b> 对 <b>{2}</b> 说:<br> </div>' ;
if (msgs) {
for (var i = 0; i < msgs.length; i++) {
var a = [];
for (var j = 0; j < msgs[i].receivers.length; j++) {
a.push(sessions[msgs[i].receivers[j]].loginName);
}
var chat_record =new Ext.Element(document.createElement('div'));
chat_record.addClass('chat_record');
chat_record.update('<span style="margin:0px 5px 0px 5px">'+msgs[i].content+'</span>');
Ext.getCmp("history_panel").body.appendChild(chat_record);
var canvas=new Ext.Element(document.createElement('canvas'));
var size_chat=chat_record.getSize();
if(!Ext.isIE && size_chat.height < 100) {
chat_record.setHeight(100);
size_chat.height=100;
}
canvas.setSize(size_chat.width-10,size_chat.height);
//canvas.setSize(size_chat.width-,40);
chat_record.appendChild(canvas);
if(window['G_vmlCanvasManager'] ) {
G_vmlCanvasManager.initElement(canvas.dom);
}
draw_m(chat_record.dom.lastChild,'#FFB100');
var mc = String.format(msg, msgs[i].time, sessions[msgs[i].sender].loginName, a);
Ext.getCmp("history_panel").body.insertHtml('beforeEnd',
mc);
Ext.getCmp("history_panel").body.scroll('b', 10000, {
duration:0.1
});
}
if(!chatWin.isVisible()){
self.focus();
Ext.example.msg('叮当',
'您有新的短消息 <a href="javascript:window.startChatWin()">查看</a>');
}
}
}
else if(response.responseText)
alert(response.responseText);
} else {
if(response.responseText)
alert(response.responseText);
}
}
}
//chatWin.show();
//chatWin.setSize(0,0);
//chatWin.hide();
if(!Ext.isIE) {
chatWin.collapse();
}
var chatTask = {
run:reloadUser,
//scope:this,
interval: 5000 //1 second
};
time_pro = new Ext.util.TaskRunner();
time_pro.start(chatTask);
//chatWin.hide();
window.startChatWin = function (){
chatWin.show();
chatWin.center();
//Ext.getCmp('htmleditor').focus();
};
function draw_m(canvas,color){
var context = canvas.getContext("2d");
var width=canvas.width;
var height2=canvas.height-4.5;
var height=canvas.height;
context.beginPath();
context.strokeStyle = color;
context.moveTo(0.5,0.5+5);
context.arc(5.5,5.5,5,-Math.PI,-Math.PI/2,false);
context.lineTo(width-0.5-5,0.5);
context.arc(width-0.5-5,5.5,5,-Math.PI/2,0,false);
context.lineTo(width-0.5,height2-5);
context.arc(width-0.5-5,height2-5,5,0,Math.PI/2,false);
context.lineTo(width/2+3,height2);
context.lineTo(width/2,height);
context.lineTo(width/2-3,height2);
context.lineTo(0.5+5,height2);
context.arc(0.5+5,height2-5,5,Math.PI/2,Math.PI,false);
context.lineTo(0.5,0.5+5);
context.stroke();
}
});
后台 见附件 ,主要是还要设一下 sessionListener
ExtJS聊天应用实践
本文介绍了一款基于ExtJS框架的聊天应用实现细节,包括窗口布局、用户面板、消息发送及接收等功能,并通过异步请求更新在线用户和聊天记录。
7347

被折叠的 条评论
为什么被折叠?



