CYQ.Data 轻量数据层之路 应用示例二 在线聊天(六)

    xiaoxiao2022-07-09  197

    继上一篇:CYQ.Data 轻量数据层之路 华丽升级 V1.3出世(五),本篇趁周末而且是下班时间看贴人不多,低调让其出手应用一下:

    同样为了能一篇介绍完一个示例,我精简挑选了一下,本次的示例为:注册+登陆+在线聊天[省去了私聊部分]

    在看此文示例之前,请先看:CYQ.Data 轻量数据层之路 应用示例篇(四) --因为注册+登陆从那直接Copy的,这节就省过了。

     

    当前环境同样是:VS2005+SQL2005,以下进入正题:

    一:数据库

    起名:Chat

    两个表:Users+Message,上图:

    说明:和上一示例比较:Users表是一样的,Message表也几乎一样了。

     

    二:项目初始

    1:新建网站项目,如起名叫:Cyq.Data.ChatDemoProject

    同样产生webconfig后添加好数据库链接!

    2:添加引用:CYQ.Data.dll

    3:生成分页查询存储过程与枚举:还是页面:WriteOut.aspx,用于生成输出:

    生成分页存储过程新方法:CYQ.Data 轻量数据层之路 华丽升级 V1.3出世(五):[9:OutPutData:增加ExeCreateProc方法用于直接执行生成分页存储过程]

     

    三:项目开始:

    先上图,整体项目情况:

    1:注册用户(Login.aspx:见示例篇(四))

    2:用户登陆(Reg.aspx:见示例篇(四))

    3:在线聊天:(Default.aspx)

    先上图,聊天主界面:

    分区域说明:

    1:左侧区为聊天显示区 2:右侧上头为欢迎与退出 3:右侧下头为用户列表区 4:底部就是留言区了 5:ajax定时刷新用2.0内置ICallBack接口实现。

     

     

    下面进行代码解说:

    页面进来时,把能加载的都加载完:只有三个点[1:登陆者名称;2:用户列表;3:默认取10条留言显示]

    1:登陆者名称与退出事件

         void  LoadMyInfo()     {          if  (Session[ " ID " ==   null )         {             Response.Redirect( " Login.aspx " );         }          else         {             Session[ " ID " =  Session[ " ID " ];             myID  = Convert.ToInt32(Session[ " ID " ]);             MAction action  =   new  MAction(TableNames.Users);              if  (action.Fill(myID))             {                 action.SetTo(labUserName);             }              else             {                 labUserName.Text  =   " 读取数据失败! " ;             }             action.Close();         }     }      protected   void  btnLogout_Click( object  sender, EventArgs e)     {         Session[ " ID " =   null ;         Response.Redirect( " Login.aspx " );     }

     

    2与3:绑定用户列表与后十条留言

         void  LoadListInfo()     {          int  rowCount;         MAction action  =   new  MAction(TableNames.Users); // 加载用户列表         rptUserList.DataSource  =  action.Select( 0 , 0 , " ID<> " + myID, out  rowCount);         rptUserList.DataBind();          if  (action.ResetTable(CustomerSQL.Message)) // 切换表到留言列表,加载留言列表         {             rptMessageList.DataSource  =  action.Select( 1 10 "" out  rowCount);             rptMessageList.DataBind();             action.Close();         }     }

     

    上面又有一个自定义的CustomerSQL.Message,其实我应该用一下存储过程来演示的,算了,写都写了:

    还是和上次演示一下,自定义语句放到类里统一管理了:

    ///   <summary> ///  by 路过秋天  http://cyq1162.cnblogs.com/ ///   </summary> public   class  CustomerSQL {      public   const   string  Message  =   " (SELECT m.*,uA.UserName,isnull(uB.UserName,'所有人') AS UserName2 FROM Message m LEFT JOIN Users uA ON m.SendUserID=uA.ID LEFT JOIN Users uB ON m.RecvUserID=uB.ID) v " ; }

     

     

    4:接下来是Ajax部分了

    这里我封装了一下,新建了个PageBase类放里面了,看一下PageBase.cs代码:

    ///   <summary> ///  路过秋天  http://cyq1162.cnblogs.com ///   </summary> public   class  PageBase:System.Web.UI.Page,ICallbackEventHandler {      #region  ICallbackEventHandler 成员      ///   <summary>      ///  Ajax方法时的回调结果      ///   </summary>      public   string  ajaxCallBackResult  =   null ;      ///   <summary>      ///  注册Ajax方法      ///  调用方法名:callAjax(arg)      ///  回调方法名:callBack(result)      ///   </summary>      public   void  RegisterAjax()     {         RegisterAjax( this " callAjax " " callBack " );     }      public   void  RegisterAjax(Control ct,  string  functionName,  string  callBackName)     {          if  ( ! ct.Page.ClientScript.IsClientScriptBlockRegistered(functionName))         {              string  callBack  =  ct.Page.ClientScript.GetCallbackEventReference(ct,  " arg " , callBackName,  null );              string  clientFunction  =   " function  "   +  functionName  +   " (arg){ "   +  callBack  +   " } " ;             ct.Page.ClientScript.RegisterClientScriptBlock(ct.Page.GetType(), functionName, clientFunction,  true );         }     }      public   string  GetCallbackResult()     {          return  ajaxCallBackResult;     }      public   virtual   void  RaiseCallbackEvent( string  eventArgument)     {              }      public   virtual   void  RegisterCommonScript()     {          const   string  script  =   @" function $(id){return document.getElementById(id)}function $V(id,defaltValue){if($(id)){if(defaltValue && $(id).value.length==0){return defaltValue;} else{return $(id).value;}}return '';} " ;         Page.ClientScript.RegisterClientScriptBlock( this .Page.GetType(),  " GetBy " , script,  true );     }      #endregion }

     

    OK,现在看一下Default.aspx的Page_Load里调用一下:

    public   partial   class  _Default :PageBase {      int  myID;      protected   void  Page_Load( object  sender, EventArgs e)     {         LoadMyInfo();         LoadListInfo();         RegisterCommonScript();         RegisterAjax();     } // ...省略N行代码... }

     

    其实,Ajax只有两部分:

    1:点提交时,用户消息要ajax提交到后台入库: 2:用户定时去取消息

     

     

    关于这两个,我们看一下ICallBack的实现:

    public   override   void  RaiseCallbackEvent( string  eventArgument)     {          int  splitIndex  =  eventArgument.IndexOf( ' : ' );          string  cmd  =  eventArgument.Substring( 0 , splitIndex);          string  data  =  eventArgument.Substring(splitIndex + 1 );          switch  (cmd)         {              case   " 0 " : // 送发消息                 ajaxCallBackResult  =   " 0 "   +  Send(data);                  break ;              case   " 1 " : // 查询消息                 ajaxCallBackResult  =   " 1 "   +  GetMessage(data);                  break ;         }     }

    接收时:该代码和前台html约定好分隔符,这里为“:”号;

    返回时:也要约定好分隔符,这里为“”号;

     

    接下来就是实现两个函数Send与GetMessage了。

    看下Send:

      string  Send( string  msg)     {          int  splitIndex = msg.IndexOf( ' : ' );          string [] content  =  msg.Split( ' ' ); // 内容为接收者ID消息内容          MAction action  =   new  MAction(TableNames.Message);         action.Set(Message.SendUserID, myID);         action.Set(Message.RecvUserID,msg.Substring( 0 ,splitIndex));         action.Set(Message.Body, msg.Substring(splitIndex + 1 ));          string  result  =  action.Insert()  ?   " 1 "  :  " 0 " ;          return  result;     }

     

    再看下GetMessage:

    private   const   string  msg  =   " <div class=\ " msg\ " ><font color=\ " Olive\ " >{0}</font> 对 <font color=\ " Olive\ " >{1}</font> 说 <font color=\ " Olive\ " >{2}</font><br /><p>{3}</p></div> " ;      string  GetMessage( string  maxID)     {          string  result = "" ;         MAction action  =   new  MAction(CustomerSQL.Message);          if  (maxID  == " 0 " )         {              if  (action.Fill( " 1=1 order by id desc " )) // 取最大ID返回             {                 result  =  action.Get < string > (Message.ID) + " " ;                 action.Close();             }         }          else         {              int  rowCount;             MDataTable mTable  =  action.Select( 0 0 string .Format( " ID>{0} and SendUserID<>{1} and (RecvUserID=0 or RecvUserID={1}) " , maxID, myID),  out  rowCount);             action.Close();              if  (rowCount  >   0 )             {                 result  =  mTable.Rows[rowCount  -   1 ][ " ID " ].Value  +   " " ;                  foreach  (MDataRow row  in  mTable.Rows)                 {                     result  +=   string .Format(msg,row[ " UserName " ].Value, row[ " UserName2 " ].Value,row[ " PubTime " ].Value,row[ " Body " ].Value);                 }             }              else             {                 result  +=  maxID  +   " " ;             }         }          return  result;     }

    代码有点长,似乎不太好理解,因为和前台html界面相关的关系:其实就是组合字符串输出了。

     

    5:前台HTML/JS

    发送消息时:

    // 组合成 命令:用户ID:留言内容 callAjax( " 0: " + $V( ' hdfUserID ' ) + " : " + $( ' txtBody ' ).innerHTML);

     

    接收消息时:

    // 组合成 命令:最大消息ID callAjax( " 1: " + msgMaxID);

     

    回调时结果:

        function callBack(result)     {        var  items=result.split('');              switch(items[0])         {             case "0"://发送消息返回结果                 $('btnSend').disabled=false;                 add($V('hdfBody'));                 break;             case "1"://查询返回结果                 if(items.length>1)                 {                     msgMaxID=items[1];                 }                 if(items.length>2)                 {                     add(items[2]);                 }                 break;         }    }    function add(msg)    {         if(msg)         {              $('left').innerHTML+=msg;              $('left').scrollTop=$('left').scrollHeight;//滚动条定位到最后面         }    }

     

    其余具体html代码就不详细贴出来了,因为我知道,我上面代码贴的再详细,估计也没多少人看,大伙看个开头,然后往下拉,看到源码下载,点击下载,差不多就拍拍屁股走人了

    不过还是要提供整个示例下载:点击下载 [数据库创建脚本在App_Data目录下]

     

     欢迎感兴趣读者讨论与留言:[上面代码注释太少,在测试使用中,如有不明请留言]。[写个示例花了1小时,写篇文章花了一天了,不容易啊!]

    版权声明:本文原创发表于博客园,作者为路过秋天,原文链接: http://www.cnblogs.com/cyq1162/archive/2010/08/21/1805018.html 相关资源:敏捷开发V1.0.pptx
    最新回复(0)