小牛的专栏

生命并非一個發現的過程,而是一個創造的過程。你并不是在發現你自己,而是在重新創造你自己。所以,別急于決定你是誰,而該急于決定你想做誰。

用户操作
[即时聊天] [发私信] [加为好友]
梦幻づ小牛ID:Self131
3645次访问,排名2万外,好友0人,关注者1人。
Self131的文章
原创 7 篇
翻译 0 篇
转载 0 篇
评论 8 篇
最近评论
kkun_3yue3:很强大!~
undertaker31:能否把数据库也提供下载呢?谢谢
sky_angles:加我msn:qzfly_sky@hotmail.com
lxzheng:能发一份代码吗?
lxzheng5566@163.com
拜托。。。。呵呵
superdont:遇到同样的问题。谢谢!
文章分类
    收藏
      相册
      存档
      订阅我的博客
      XML聚合  FeedSky

      原创 WebQQ 实现收藏

       | 旧一篇: JSLINQ-LINQ to JavaScript 总结

              使用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这样为每个用户创建一个数据库,因时因地而异。)

      我还是先贴个图,诱惑一下。^_^

       

      WebQQ主界面

      聊天窗口

       

      这里也有全部源代码地址:http://download.csdn.net/source/499268 下面贴部分代码: 

      服务器端消息处理页面:
      GetChatMessage.aspx
      public partial class GetChatMessage : System.Web.UI.Page
      {
          protected void Page_Load(object sender, EventArgs e)
          {
              string userinfoPath = Request.MapPath(@"\\db\userinfo.db3");
              string userPath = Request.MapPath(@"\db\userdb\");
      
              string username = Request.Params["username"];
              if (username != null)
              {
                  IChat chat = new Chat(userinfoPath, userPath);
                  string str = chat.GetChatMessage(username);
                  Response.Write(str);
              }
              Response.End();
          }
      } 
      SendChatMessage.aspx 
      public partial class SendChatMessage : System.Web.UI.Page
      {
          protected void Page_Load(object sender, EventArgs e)
          {
              string userinfoPath = Request.MapPath(@"\db\userinfo.db3");
              string userPath = Request.MapPath(@"\db\userdb\");
      
              string fromusername = Request.Params["fromusername"];
              string tousername = Request.Params["tousername"];
              string message = Request.Params["message"];
              if (fromusername != null && tousername != null && message != null)
              {
                  IChat chat = new Chat(userinfoPath,userPath);
                  chat.SendChatMessage(fromusername, tousername, message);
                  Response.Write("{success:true}");
              }
              else
                  Response.Write("{success:false}");
              Response.End();
          }
      } 
      
      
      聊天消息处理接口:
          interface IChat
          {
              string GetChatMessage(string userName);
              void SendChatMessage(string toUserName, string fromUserName, string message);
          }
       
       
      聊天消息处理类:
      (数据库,我临时使用Sqlite3,创建了一个userinfo.db3存储全部用户的信息,并且创建chatlastid表,存储每个用户的LastChatID。我为每个用户都创建了一个个人的数据库文件,如snail.db3,oo.db3.存储他自己的消息(chatmsg表).)
       public class Chat: IChat
      {
          private string userinfoDBPath = "";
          private string userDBPath = "";
          public Chat(string userinfoStr,string userStr)
          {
              this.userinfoDBPath = userinfoStr;
              this.userDBPath = userStr;
          }
      
          /// <summary>
          /// 根据用户名获取最后一次发送或接受消息的ID
          /// </summary>
          /// <param name="userName">欲获取其LastChatID的用户</param>
          private int GetLastChatID(string userName)
          {
              int returnValue = -1;
              using(SQLiteConnection conn = new SQLiteConnection("Data Source=" + userinfoDBPath))
              {
                  try
                  {
                      conn.Open();
                      string strsql = "select [lastchatid] from [chatlastid] where username = @userName";
                      SQLiteCommand cmd = new SQLiteCommand(strsql, conn);
                      cmd.Parameters.AddWithValue("@userName", userName);
                      object result = cmd.ExecuteScalar();
                      conn.Clone();
                      if (result == null)
                          SetDefaultLastChatID(userName);
                      else
                          returnValue = Convert.ToInt32(result);
                  }
                  catch (Exception ex)
                  {
                  }
                  finally
                  {     
                  }
              }
              return returnValue;
          }
      
      
          /// <summary>
          /// 如果用户在ChatLastID表中没有值,则设置其为默认值-1
          /// </summary>
          /// <param name="userName">用户名</param>
          private void SetDefaultLastChatID(string userName)
          {
              int defaultLastID = -1;
              using(SQLiteConnection conn = new SQLiteConnection("Data Source=" + userinfoDBPath))
              {
                  try
                  {
                      conn.Open();
                      string strsql = "insert into chatlastid(username,lastchatid) values(@userName,@lastchatid)";
                      SQLiteCommand cmd = new SQLiteCommand(strsql, conn);
                      cmd.Parameters.AddWithValue("@userName", userName);
                      cmd.Parameters.AddWithValue("@lastchatid", defaultLastID);
                      cmd.ExecuteNonQuery();
                  }
                  catch (Exception ex)
                  {
                  }
                  finally
                  {
                      conn.Clone();
                  }
              }
          }
      
      
          /// <summary>
          /// 获取某个用户的消息列表,string类型,并且在获取消息的同时设置LastID。
          /// </summary>
          /// <param name="userName">欲获取消息的用户名</param>
          public string GetChatMessage(string userName)
          {
              string returnStr = "";
              int lastID = GetLastChatID(userName);
              int freshID = GetFreshChatID(userName);
              if (freshID > lastID)
              {
                  string datapath = userDBPath + userName + @".db3";
                  int getChatID = freshID - lastID;
                  using(SQLiteConnection conn = new SQLiteConnection("Data Source=" + datapath))
                  {
                      DataSet ds = new DataSet();
                      try
                      {
                          conn.Open();
                          string strsql = "select [chatid],[fromusername],[message],[senddate] from (Select [chatid],[fromusername],[message],[senddate] From [chatmsg] order by chatid desc limit "+getChatID+") order by chatid asc";
                          SQLiteDataAdapter sdap = new SQLiteDataAdapter(strsql , conn);
                          sdap.Fill(ds);
                          conn.Clone();
      		  //将DataSet转化为JSON格式
                          returnStr = JSONHelper.Convert2Json(ds);
                          //设置LastChatID值chatlastid Table
                          SetLastChatID(userName, freshID);
                      }
                      catch (Exception ex)
                      {
                      }
                      finally
                      {                
                      }
                  }
              }
              return returnStr;
          }
      
      
          /// <summary>
          /// 给指定用户名发送消息,保存至该用户个人数据库。(发送时间在插入数据的时候获取当前时间。)
          /// </summary>
          /// <param name="toUserName">消息接收者名称</param>
          /// <param name="fromUserName">消息发送者名称</param>
          /// <param name="message">消息内容</param>
      
          public void SendChatMessage(string fromUserName, string toUserName, string message)
          {
              string senddate = DateTime.Now.ToString("u").TrimEnd('Z');
              string datapath = userDBPath + toUserName + @".db3";
              using (SQLiteConnection conn = new SQLiteConnection("Data Source=" + datapath))
              {
                  try
                  {
                      conn.Open();
                      string strsql = "insert into chatmsg(fromusername,message,senddate) values(@fromUserName,@message,@senddate);";
                      SQLiteCommand cmd = new SQLiteCommand(strsql, conn);
                      cmd.Parameters.AddWithValue("@fromUserName", fromUserName);
                      cmd.Parameters.AddWithValue("@message", message);
                      cmd.Parameters.AddWithValue("@senddate", senddate);
                      cmd.ExecuteNonQuery();
                  }
                  catch (Exception ex)
                  {
                  }
                  finally
                  {
                      conn.Clone();
                  }
              }
          }
      
      
          /// <summary>
          /// 设置公用数据库ChatLastID中的某个用户的LastID
          /// </summary>
          /// <param name="userName">欲设置ChatLastID的用户</param>
          private void SetLastChatID(string userName, int lastchatid)
          {
              using(SQLiteConnection conn = new SQLiteConnection("Data Source=" + userinfoDBPath))
              {
                  try
                  {
                      conn.Open();
                      string strsql = "update [chatlastid] set [lastchatid] = @lastchatid where [username] = @userName";
                      SQLiteCommand cmd = new SQLiteCommand(strsql, conn);
                      cmd.Parameters.AddWithValue("@userName", userName);
                      cmd.Parameters.AddWithValue("@lastchatid", lastchatid);
                      cmd.ExecuteNonQuery();
                  }
                  catch (Exception ex)
                  {
                  }
                  finally
                  {
                      conn.Clone();
                  }
              }
          }
      
      
          /// <summary>
          /// 获取最新的ChatID
          /// </summary>
          /// <param name="userName">欲获取某个用户的名称</param>
          private int GetFreshChatID(string userName)
          {
              int returnValue = 0;
              string datapath = userDBPath + userName + @".db3";
              using(SQLiteConnection conn = new SQLiteConnection("Data Source=" + datapath))
              {
                  try
                  {
                      conn.Open();
                      string strsql = "Select max(chatid)  From [chatmsg];";
                      SQLiteCommand cmd = new SQLiteCommand(strsql, conn);
                      returnValue = Convert.ToInt32(cmd.ExecuteScalar());
                  }
                  catch (Exception ex)
                  {
                  }
                  finally
                  {
                      conn.Clone();
                  }
              }
              return returnValue;
          }
      } 
      

      chatmsg 表:

      Create  [chatmsg](
      [chatid] INTEGER PRIMARY KEY NOT NULL
      ,[fromusername] nvarchar(20) NOT NULL
      ,[message] nvarchar(200)
      ,[senddate] nvarchar(20)
      ); 
      
      chatlastid 表:
      Create  [chatlastid](
      [username] nvarCHAR(20) PRIMARY KEY NOT NULL
      ,[lastchatid] INTEGER NOT NULL DEFAULT '0'
      );
      
      这个WebQQ有很多的不足之处,很多编码思想,编码规范等等都由这个自己来的,怎么想就做么做了,呵呵。如果你有好的建议,意见,咱多聊聊。^_^
      
      
       

      发表于 @ 2008年06月16日 13:01:00|评论(loading...)|收藏

       | 旧一篇: JSLINQ-LINQ to JavaScript 总结

      评论

      #lxzheng 发表于2008-06-16 14:36:39  IP: 123.112.88.*
      能发一份代码吗?
      lxzheng5566@163.com
      拜托。。。。呵呵
      #sky_angles 发表于2008-07-30 20:55:26  IP: 221.221.212.*
      加我msn:qzfly_sky@hotmail.com
      #undertaker31 发表于2008-08-21 12:47:55  IP: 59.38.25.*
      能否把数据库也提供下载呢?谢谢
      发表评论  


      登录
      Csdn Blog version 3.1a
      Copyright © 梦幻づ小牛