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

继上一篇: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

时间: 2024-12-03 14:13:00

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

CYQ.Data 轻量数据层之路 应用示例三 Aop切入留言系统--操作日志(二十七)

前言: 在8月份时,那时曾用CYQ.Data 1.2版本演示过一个完整的示例,留言版:详见:CYQ.Data 轻量数据层之路 应用示例一 留言版(四) 本篇将使用2.N系列版本,在不改动原来留言版系统一行代码的情况下,实现其数据库操作日志功能. 最新版本下载见:CYQ.Data 轻量数据层之路 bug反馈.优化建议.最新框架下载     正文步骤:   一:建表 1:增加一个日志操作表[ActionLogs],这个少不了,表结构如下: 2:创建表的数据库脚本如下: 创建ActionLogs表  

CYQ.Data 轻量数据层之路 终极升级(二)

在上一篇:CYQ.Data 轻量数据层之路 开篇介绍(一)中,我们介绍了基本的类库与使用介绍.   上篇留言中虽然感觉好像很平静,不过不难想象,大伙仅勿勿一眼一扫而过的那种情景: 一个很沉重的心结,一直在很多开发人员的心里挥之不去:实体类. 大伙似乎都很排拆没有实体类的数据层框架,仅因早于习惯了ORM?   其实,我记得我第一次毕设的时候,也是有实体类的: 还记得很久前,毕设做的是仿QQ空间的CQ-Space空间,借用了CodeSmith生成实体类[里面集合了增删改查],来操作数据库, 也感受到

CYQ.Data 轻量数据层之路 使用篇二曲 MAction 数据查询(十三)

上一篇:CYQ.Data 轻量数据层之路 使用篇一曲 裸身走天涯(十二)   前言说明: 本篇继续上一篇内容,本节介绍所有相关查询的使用. 主要内容提要:1:单行数据操作 Fill 操作 GetCount操作.2:多行数据操作 Select 操作3:列表绑定控件操作 配合分页控件4:多表查询及绑定 视图及自定义SQL     单行数据操作   一:Fill 填充方法,单行查询 方法原形:public bool Fill(object where) 示例1:直传ID MAction action 

CYQ.Data 轻量数据层之路 应用示例一 留言版(四)

继上篇:CYQ.Data 轻量数据层之路 继续狂热升级(三)之后,本篇要进入应用示例介绍使用了:   为了使一篇文章就能介绍完整个示例,我选用了简单的:登陆+注册+留言版本功能,来一步一步介绍如何使用的: 当前环境是:VS2005+SQL2005   从数据库说起吧,我们创建一个新的数据库,起名叫:Message 接着新建两个表:Users+Message,上图: 为避免本篇节过长,本示例只选用最关键的字段了,大伙可以根据上面的图自己创建数据库与表. 接着我们新建网站来示例[这里没选择新建应用程

CYQ.Data 轻量数据层之路 华丽V1.3版本 框架开源

本篇对框架开源进行说明:   提前说明: 1:最近有很多友人没有留言就加群了,导致被拒绝,这此说声抱歉啦.    不过规则还是要遵守的,毕竟人数有限.    如果只是想着可有可无的看,下面有一份反编绎源码,基本也不影响高手查看了. 2:另外也有个别留了言没加群的,也只能说声音抱歉了,源码不会发到指定的邮箱.    源码会发送到指定邮箱的情况:仅限于公司名义,同时站内信有消息,才会特别去发邮件的.       本次开源针对最新版本V1.3版本,相关更新见:CYQ.Data 轻量数据层之路 华丽升级

CYQ.Data 轻量数据层之路 使用篇一曲 裸身走天涯(十二)

其实本来是不想写使用帮助的,因为在以下的文章中,都有大量的示例存在:   CYQ.Data 轻量数据层之路 应用示例一 留言版(四) CYQ.Data 轻量数据层之路 华丽升级 V1.3出世(五) CYQ.Data 轻量数据层之路 应用示例二 在线聊天(六) CYQ.Data 轻量数据层之路 优雅V1.4 现世 附API帮助文档(九)   不过很多人还是很懒啊,一进群就用问怎么用. 发个文章路径让其看吧,又说太麻烦,使用复杂,于是想了想,还是写写使用教程,让这部分懒人速成一下.   当前最新版本

CYQ.Data 轻量数据层之路 SQLHelper 回头太难(八)

提前说明:正如网友反映的一样,为了不至于产生明显的误导,特别加了此首段说明 SQLHelper,几乎是每个过来者必经的阶段,写好一个SQLHelper是非常重要的一环,所以希望年轻的来者,要多加实践,别只看不动手,哪怕照着写一写,也是相当的有益. 对于本框架系列,希望年轻来者在掌握使用的同时,动手照着系列文章写一写,如果照着写出来的,相信成长不是一点半点的:别光看不练,最后只能忽悠却动不了手.       这篇文章很不好写,我在电脑前思索了一天,也不知怎么下手. 关于SQLHelper的文章遍地

CYQ.Data 轻量数据层之路 继续狂热升级(三)

在上一篇:CYQ.Data 轻量数据层之路 终极升级(二) 之时,我通过新增加GetFrom与SetTo方法,来避免直接使用索引的取值和赋值的不便.   本来,今天是打算写个实例教程,来简单介绍用这个超轻量框架进行开发是有多轻松的事情,不过在使用时,还是发现了个别的小bug. 于是,今天狂热的修改了N多代码,抽取Sql组成部分到单独的类中,继续去掉N多重载方法,留下最简洁最实用的方法.   以面看看有哪些改进: 数据库配置假设如下: <connectionStrings>         &l

CYQ.Data 轻量数据层之路 华丽升级 V1.3出世(五)

继上一篇:CYQ.Data 轻量数据层之路 应用示例篇(四) 之后,有兴趣的读者可以放心使用及应用或练习了!   不过,在稳定版本之后,本人又进行了一次华丽的升级,升级记录如下: 1:MAction:增加ResetTable功能 2:MAction:增加在Update/Insert/Fill/ResetTable失败时,自动调用Close() 3:MAction:修改Fill方法:将之前如果填充时有多条记录返回失败,改成返回首条记录 4:MAction:增加SetAutoPrefix方法,可传多