使用ExtJS创建前端WebQQ界面,使用ASP.NET处理数据存取,为了演示方便用Sqlite3存储数据。
功能概述:
实现了最基础的一对一的通讯功能,实时收发信息,离线保存信息。来信自动弹出窗口。
实现思路:
借鉴了早些年的聊天室思想。
获取聊天信息是客户端定时向服务器请求,按照发送的用户名来查询此用户是否有新信息。有信息则返回信息。如何获取?思路如下:
数据库中为每个用户设置一个
LastID
,获取信息的时候比较聊天信息表中最大的
ChatID
。如果
ChatID
大于
LastID
,则表明有新的聊天信息,接着从对应数据库获取聊天信息
( ChatID-LastID
表明新信息条数
),
返回给客户端。客户端再根据不同的用户名,将信息追加到相应的聊天窗口。这里还有一步,设置
LastID
,将这个最大的
ChatID
保存为
LastID
。
发送聊天信息比较好理解,
POST
数据至服务器端的处理页面,进行保存即可。
实现细节:
客户端:
主要有4个处理函数:
双击用户名节点创建聊天窗口:
webQQDblClick()
来信动态创建聊天窗口
:
autoshowQQWindow()
定时从服务器获取聊天消息
:
loadMessage()
向聊天窗口追加聊天信息:
addMessage()
发送聊天信息的处理语句分别在
webQQDblClick()
和
autoshowQQWindow()里面都有。当然这样处理是不符合一些设计思想的,多敲了很多代码。我是懒得封装成一个方法。
服务器端:
有两个处理页面:
一个保存提交的聊天信息页面:SendChatMessage.aspx
一个获取聊天信息的页面:GetChatMessage.aspx
主要的获取数据和保存信息的处理方法是在Chat类中定义的。


申明一下:我仅仅是实现了WebQQ的部分功能。并非实现合理。首先我的编码不是很规范。请谅解。其次WebQQ界面是ExtJS的Desktop例子 中的那个。稍稍把代码改一下,就可以独立了!还有QQ好友不是异步动态获取的。 我为每个用户都创建了一个数据库文件,这是因为Sqlite操作方便。还有每个用户都有很多不同的数据要存储,不仅仅是保存了聊天信息,所以才这样的。其 实你可以把Sqlite看成是一个文本文件,只不过是用关系数据库的方式来思考和存取。想象一下,如果你的一个文本文件,有10M大小。你用文本编辑器打 开时什么感觉。我宁可把它分解成50个,500个文本进行读取。这是我的看法!
还有使用Sqlite是为了演示方便,不需要任何安装、配置、管理。
(其他数据库估计就不能这样了!如果我用MSSQL也绝不会像处理Sqlite这样为每个用户创建一个数据库,因时因地而异。)
我还是先贴个图,诱惑一下。^_^
![]()
![]()
这里也有全部源代码地址:http://download.youkuaiyun.com/source/499268 下面贴部分代码:
- 服务器端消息处理页面:
- GetChatMessage.aspx
-
- publicpartialclassGetChatMessage:System.Web.UI.Page
- {
- protectedvoidPage_Load(objectsender,EventArgse)
- {
- stringuserinfoPath=Request.MapPath(@"//db/userinfo.db3");
- stringuserPath=Request.MapPath(@"/db/userdb/");
-
- stringusername=Request.Params["username"];
- if(username!=null)
- {
- IChatchat=newChat(userinfoPath,userPath);
- stringstr=chat.GetChatMessage(username);
- Response.Write(str);
- }
- Response.End();
- }
- }
- publicpartialclassGetChatMessage:System.Web.UI.Page
- {
- protectedvoidPage_Load(objectsender,EventArgse)
- {
- stringuserinfoPath=Request.MapPath(@"//db/userinfo.db3");
- stringuserPath=Request.MapPath(@"/db/userdb/");
-
- stringusername=Request.Params["username"];
- if(username!=null)
- {
- IChatchat=newChat(userinfoPath,userPath);
- stringstr=chat.GetChatMessage(username);
- Response.Write(str);
- }
- Response.End();
- }
- }
-
- SendChatMessage.aspx
- SendChatMessage.aspx
-
- publicpartialclassSendChatMessage:System.Web.UI.Page
- {
- protectedvoidPage_Load(objectsender,EventArgse)
- {
- stringuserinfoPath=Request.MapPath(@"/db/userinfo.db3");
- stringuserPath=Request.MapPath(@"/db/userdb/");
-
- stringfromusername=Request.Params["fromusername"];
- stringtousername=Request.Params["tousername"];
- stringmessage=Request.Params["message"];
- if(fromusername!=null&&tousername!=null&&message!=null)
- {
- IChatchat=newChat(userinfoPath,userPath);
- chat.SendChatMessage(fromusername,tousername,message);
- Response.Write("{success:true}");
- }
- else
- Response.Write("{success:false}");
- Response.End();
- }
- }
聊天消息处理接口: -
- interfaceIChat
- {
- stringGetChatMessage(stringuserName);
- voidSendChatMessage(stringtoUserName,stringfromUserName,stringmessage);
- }
聊天消息处理类:- 聊天消息处理类:
- (数据库,我临时使用Sqlite3,创建了一个userinfo.db3存储全部用户的信 息,并且创建chatlastid表,存储每个用户的LastChatID。我为每个用户都创建了一个个人的数据库文件,如 snail.db3,oo.db3.存储他自己的消息(chatmsg表).)
- publicclassChat:IChat
- {
- privatestringuserinfoDBPath="";
- privatestringuserDBPath="";
- publicChat(stringuserinfoStr,stringuserStr)
- {
- this.userinfoDBPath=userinfoStr;
- this.userDBPath=userStr;
- }
- ///<summary>
- ///根据用户名获取最后一次发送或接受消息的ID
- ///</summary>
- ///<paramname="userName">欲获取其LastChatID的用户</param>
- privateintGetLastChatID(stringuserName)
- {
- intreturnValue=-1;
- using(SQLiteConnectionconn=newSQLiteConnection("DataSource="+userinfoDBPath))
- {
- try
- {
- conn.Open();
- stringstrsql="select[lastchatid]from[chatlastid]whereusername=@userName";
- SQLiteCommandcmd=newSQLiteCommand(strsql,conn);
- cmd.Parameters.AddWithValue("@userName",userName);
- objectresult=cmd.ExecuteScalar();
- conn.Clone();
- if(result==null)
- SetDefaultLastChatID(userName);
- else
- returnValue=Convert.ToInt32(result);
- }
- catch(Exceptionex)
- {
- }
- finally
- {
- }
- }
- returnreturnValue;
- }
- ///<summary>
- ///如果用户在ChatLastID表中没有值,则设置其为默认值-1
- ///</summary>
- ///<paramname="userName">用户名</param>
- privatevoidSetDefaultLastChatID(stringuserName)
- {
- intdefaultLastID=-1;
- using(SQLiteConnectionconn=newSQLiteConnection("DataSource="+userinfoDBPath))
- {
- try
- {
- conn.Open();
- stringstrsql="insertintochatlastid(username,lastchatid)values(@userName,@lastchatid)";
- SQLiteCommandcmd=newSQLiteCommand(strsql,conn);
- cmd.Parameters.AddWithValue("@userName",userName);
- cmd.Parameters.AddWithValue("@lastchatid",defaultLastID);
- cmd.ExecuteNonQuery();
- }
- catch(Exceptionex)
- {
- }
- finally
- {
- conn.Clone();
- }
- }
- }
- ///<summary>
- ///获取某个用户的消息列表,string类型,并且在获取消息的同时设置LastID。
- ///</summary>
- ///<paramname="userName">欲获取消息的用户名</param>
- publicstringGetChatMessage(stringuserName)
- {
- stringreturnStr="";
- intlastID=GetLastChatID(userName);
- intfreshID=GetFreshChatID(userName);
- if(freshID>lastID)
- {
- stringdatapath=userDBPath+userName+@".db3";
- intgetChatID=freshID-lastID;
- using(SQLiteConnectionconn=newSQLiteConnection("DataSource="+datapath))
- {
- DataSetds=newDataSet();
- try
- {
- conn.Open();
- stringstrsql="select[chatid],[fromusername],[message],[senddate]from(Select[chatid],[fromusername],[message],[senddate]From[chatmsg]orderbychatiddesclimit"+getChatID+")orderbychatidasc";
- SQLiteDataAdaptersdap=newSQLiteDataAdapter(strsql,conn);
- sdap.Fill(ds);
- conn.Clone();
- //将DataSet转化为JSON格式
- returnStr=JSONHelper.Convert2Json(ds);
- //设置LastChatID值chatlastidTable
- SetLastChatID(userName,freshID);
- }
- catch(Exceptionex)
- {
- }
- finally
- {
- }
- }
- }
- returnreturnStr;
- }
- ///<summary>
- ///给指定用户名发送消息,保存至该用户个人数据库。(发送时间在插入数据的时候获取当前时间。)
- ///</summary>
- ///<paramname="toUserName">消息接收者名称</param>
- ///<paramname="fromUserName">消息发送者名称</param>
- ///<paramname="message">消息内容</param>
- publicvoidSendChatMessage(stringfromUserName,stringtoUserName,stringmessage)
- {
- stringsenddate=DateTime.Now.ToString("u").TrimEnd('Z');
- stringdatapath=userDBPath+toUserName+@".db3";
- using(SQLiteConnectionconn=newSQLiteConnection("DataSource="+datapath))
- {
- try
- {
- conn.Open();
- stringstrsql="insertintochatmsg(fromusername,message,senddate)values(@fromUserName,@message,@senddate);";
- SQLiteCommandcmd=newSQLiteCommand(strsql,conn);
- cmd.Parameters.AddWithValue("@fromUserName",fromUserName);
- cmd.Parameters.AddWithValue("@message",message);
- cmd.Parameters.AddWithValue("@senddate",senddate);
- cmd.ExecuteNonQuery();
- }
- catch(Exceptionex)
- {
- }
- finally
- {
- conn.Clone();
- }
- }
- }
- ///<summary>
- ///设置公用数据库ChatLastID中的某个用户的LastID
- ///</summary>
- ///<paramname="userName">欲设置ChatLastID的用户</param>
- privatevoidSetLastChatID(stringuserName,intlastchatid)
- {
- using(SQLiteConnectionconn=newSQLiteConnection("DataSource="+userinfoDBPath))
- {
- try
- {
- conn.Open();
- stringstrsql="update[chatlastid]set[lastchatid]=@lastchatidwhere[username]=@userName";
- SQLiteCommandcmd=newSQLiteCommand(strsql,conn);
- cmd.Parameters.AddWithValue("@userName",userName);
- cmd.Parameters.AddWithValue("@lastchatid",lastchatid);
- cmd.ExecuteNonQuery();
- }
- catch(Exceptionex)
- {
- }
- finally
- {
- conn.Clone();
- }
- }
- }
- ///<summary>
- ///获取最新的ChatID
- ///</summary>
- ///<paramname="userName">欲获取某个用户的名称</param>
- privateintGetFreshChatID(stringuserName)
- {
- intreturnValue=0;
- stringdatapath=userDBPath+userName+@".db3";
- using(SQLiteConnectionconn=newSQLiteConnection("DataSource="+datapath))
- {
- try
- {
- conn.Open();
- stringstrsql="Selectmax(chatid)From[chatmsg];";
- SQLiteCommandcmd=newSQLiteCommand(strsql,conn);
- returnValue=Convert.ToInt32(cmd.ExecuteScalar());
- }
- catch(Exceptionex)
- {
- }
- finally
- {
- conn.Clone();
- }
- }
- returnreturnValue;
- }
- }
chatmsg 表:
chatmsg 表:
Create [chatmsg]( [chatid] INTEGER PRIMARY KEY NOT NULL ,[fromusername] nvarchar(20) NOT NULL ,[message] nvarchar(200) ,[senddate] nvarchar(20) );- Create[chatmsg](
- [chatid]INTEGERPRIMARYKEYNOTNULL
- ,[fromusername]nvarchar(20)NOTNULL
- ,[message]nvarchar(200)
- ,[senddate]nvarchar(20)
- );
chatlastid 表:- chatlastid表:
Create [chatlastid]( [username] nvarCHAR(20) PRIMARY KEY NOT NULL ,[lastchatid] INTEGER NOT NULL DEFAULT '0' );- Create[chatlastid](
- [username]nvarCHAR(20)PRIMARYKEYNOTNULL
- ,[lastchatid]INTEGERNOTNULLDEFAULT '0'
- );
- 这个WebQQ有很多的不足之处,很多编码思想,编码规范等等都由这个自己来的,怎么想就做么做了,呵呵。如果你有好的建议,意见,咱多聊聊。^_^
-
- <PRE class=jscriptname="code"></PRE>
本文介绍了一种利用ExtJS和ASP.NET构建WebQQ应用的方法,通过客户端定时向服务器请求新消息并使用Sqlite3存储数据。文章详细解释了消息发送与接收的处理流程。
293

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



