首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

18.5  Web服务层

为了调用程序方便和使程序具有可扩展性,本章把Web QQ的常用操作封装在Web服务层。Web服务层调用底层代码的功能,向Web层提供服务,属于中间层。Improve.cs是Web服务层的代码文件。这里分为4部分加以介绍:发送、接收聊天信息;添加好友;获取聊天记录;其他一些方法。

18.5.1  发送、接收聊天信息

发送、接收聊天消息主要分为两种:发送、接收两人聊天消息和发送、接收群聊天消息。其中接收两人聊天消息的处理流程相对比较复杂。其程序流程如图18.12所示。

两人聊天发送、接收聊天消息的实现代码如下:

#region 发送接受消息(两人聊天和群)

     // 两人对聊时用户发送消息

     //receiver  接受者账号;msg  消息内容

     [WebMethod]

     public void SendMsg(HttpContext context, string receiver, string msg)

     {

         //接受者未在线,直接插入数据库;

         if(context.Cache[receiver] == null)

         {

              string insertstr = "insert msg(sendername,receivername,msg) values('";

              insertstr += selfname + "','" + receiver + "','" + msg + "')";

              s.ExecuteSql(insertstr);          //执行插入操作

         }

         else                                 //在线,放入内存,等待接收。

         {

              ((ChatUser)(context.Cache[receiver])).Message.Add(selfname, msg);

         }

     }

     // 两人对聊时接收特定人给自己发的未读消息

图18.12  两人聊天接收消息的流程图

     //sender  发送者

     [WebMethod]

     public MsgTable ReceiveMsg(HttpContext context, string sender)

     {

          MsgTable Message = new MsgTable();//要返回的消息表

          //没有在线信息,直接从数据库中查找消息

          if(context.Cache[selfname] == null)

          {

               SqlDataReader dr = s.GetReader("select * from msg where sendername='"

               + sender + "' and receivername = '" + selfname + "'  and ifread =1");

               while (dr.Read())            //查找到消息,把消息添加到返回的消息表中

               {

                   Message.Add(new Msg(int.Parse(dr["id"].ToString()), dr["sendername"].

                   ToString(), dr["msg"].ToString(),

                   DateTime.Parse(dr["sendtime"].ToString()), dr["ifread"].ToString()

                   == "1" ? false : true));

               }

               dr.Close();

               //更新消息已读状态

               s.ExecuteSql("update msg set ifread=0  where sendername='" + sender

              +"' and receivername ='" + selfname + "' and ifread=1");

          }

          else                                    //有在线信息

          {

              //用户所拥有的所有消息

              MsgTable mymsg = ((ChatUser)context.Cache[selfname]).Message;

              Message.MaxRecord = 100;          //设置每个用户能存放的消息数目为100条

              string temp = "0";                //记录已经找到的消息id

              //接收在线消息

              for(int i = 0; i < mymsg.List.Count; i++)

              {

                   //此条消息正是需要找的消息

                   if (((Msg)mymsg.List[i]).IfRead == false && ((Msg)mymsg.List[i]).

                   SenderName == sender)

                   {

                         Message.Add((Msg)mymsg.List[i]);          //添加到返回表中

                         ((Msg)mymsg.List[i]).IfRead = true;

                         temp += ("," + ((Msg)mymsg.List[i]).ID);  //把id记录下

                   }

              }

              //数据库中有额外新消息

              if(mymsg.HaveOtherMsg == true)

              {

                   SqlDataReader dr = s.GetReader("select * from msg where  id not in

                   (" + temp + ") and  sendername='" + sender + "' and receivername

                   = '" + selfname + "'  and ifread =1");

                   while (dr.Read())                 //遍历取到的每条消息

                   {

                        //添加到返回表中

                        Message.Add(new Msg(int.Parse(dr["id"].ToString()), dr["sendername"].

                        ToString(), dr["msg"].ToString(), DateTime.Parse(dr["sendtime"].

                        ToString()), false));

                   }

                   dr.Close();

                   //把取走的消息更新为已读

                   s.ExecuteSql("update msg set ifread=0  where sendername='" +

                   sender + "' and receivername ='" + selfname + "' and ifread=1");

                   mymsg.HaveOtherMsg = false;       //数据库中没有额外数据了

              }

          }

          return Message;

     }

     // 发送群消息

     // msg  消息内容

     [WebMethod]

     public void SendGroupMsg(string groupid, string msg)

     {

          //当前会话上下文

          HttpContext context = HttpContext.Current;

          if(context.Cache["$" + groupid] == null)/当前不存在这个群的对象实例,创建这个群

          {

               context.Cache.Insert("$" + groupid, new MyGroup(groupid));

          }

          //构造一个新消息

          BaseMsg bm = new BaseMsg(selfname, msg);

          //添加上这个消息

          ((GroupMsgTable)(HttpContext.Current.Cache["$" + groupid])).Add(bm);

     }

     // 接受群消息

     //groupid  群组的id

     [WebMethod]

     public GroupMsgTable ReceiveGroupMsg(string groupid)

     {

          HttpContext context = HttpContext.Current;

          GroupMsgTable gmt = new GroupMsgTable(); //返回的群消息表

          if(context.Cache["$" + groupid] != null) //接受应该自己收到的群消息

               gmt = ((MyGroup)(context.Cache["$" + groupid])).ReceiveMsg();

          return gmt;

     }

     #endregion

18.5.2  添加好友

聊天者是否允许被添加为好友的设置有3种:允许任何人直接将自己添加为好友;拒绝任何人将自己添加为好友;允许经过验证的用户添加自己为好友。与之对应,添加好友时也应考虑这3种情况,分别加以处理。添加好友的流程如图18.13所示。

图18.13  添加好友的流程图

与添加好友相关的程序代码如下:

#region 添加好友的操作

     // 请求增加好友第一步;有4种返回情况:havefriend;isblack;success;confirm;forbid;

     //添加好友

     //  friendid 要添加好友的用户id

     [WebMethod]

     public string AddFriend(string friendid)

     {

         //取得好友账号

         string friendname = s.getMyDataSet("select username from userinfo where

         userid=" + friendid).Tables[0].Rows[0][0].ToString();

         //查找要添加的好友是否已经在自己的联系人列表中了

         SqlDataReader r = s.GetReader("select type from friend where userid =" +

         selfid + " and othername='" + friendname + "' and type !=2");

         if(r.Read() && r["type"].ToString() == "0")       //已经是好友了

         {

               r.Close();

               return "havefriend";

         }

         if(r.HasRows && r["type"].ToString() == "1")      //此用户在黑名单中

         {

               r.Close();

               return "isblack";

         }

         r.Close();

          //此用户被添加为好友是否需要验证

         r = s.GetReader("select canaddfriend from userinfo where userid = " + friendid);

         string flag = "";                                 //是否需要验证

         if(r.Read())

               flag = r["canaddfriend"].ToString();

         r.Close();//关闭连接

         if(flag == "1")                                      //可以直接加为好友

         {

               s.ExecuteSql("insert friend (type,userid,othername)values(0," + selfid

               + ",'" + friendname + "')", false);          //加为好友

               //对方是否把自己加为了好友或黑名单

               r = s.GetReader("select id from friend where   userid =" + friendid

               + " and othername = '" + selfname + "'");

               if(!r.HasRows)           //自己没在对方的联系人列表中,自己成为对方的陌生人

               {

                      r.Close();

                      s.ExecuteSql("insert friend (type,userid,othername)values(2," +

                      friendid + ",'" + selfname + "')");

               }

               else

                      r.Close();

               return "success";                        //添加好友成功

         }

         if(flag == "0")                                      //加为好友需要确认

         {

               return "confirm";

         }

         if(flag == "2")                                      //对方拒绝被加为好友

         {

               return "forbid";

         }

         return "";

     }

     // 添加好友第二步,发出请求加为好友的文字请求

     // friendid 要加为好友的id,notes 加为好友的请求留言

     [WebMethod]

     public void AskForAddF(string friendid, string notes)

     {

         string friendname = "";               //要加为好友的账号名

         Sql s0 = new Sql();

         SqlDataReader r0 = s0.GetReader("select username from userinfo where

         userid=" + friendid);

         if(r0.Read())                         //根据id 取得了账号名

               friendname = r0["username"].ToString();

         r0.Close();

         s0 = null;                            //清空

         HttpContext context = HttpContext.Current;

         string msg = selfname + "  请求加您为好友,您是否同意?<br/>消息:" + notes;

                                               //构造消息内容

         msg += "<a href=javascript:top.frames('chatqq').allowf(\"" + selfname +

         "\");>同意  </a>&nbsp&nbsp<a href=javascript:top.frames('chatqq').rejectf

         (\"" + selfname + "\");>不同意  </a>";

         //接受者未在线,直接存入数据库;

         if(context.Cache[friendname] == null)

         {

              string insertstr = "insert msg(sendername,receivername,msg) values('";

              insertstr += ("qucha" + "','" + friendname + "','" + msg + "')");

              s.ExecuteSql(insertstr);          //存入数据库

         }

         else                                 //在线,放入内存,等待接收。

         {

              Msg mymsg = new Msg("qucha", msg);

              ((ChatUser)(context.Cache[friendname])).Message.Add(mymsg);

         }

     }

     // 添加好友第三步,同意被加为好友

     //    friendname 好友账号

     [WebMethod]

     public void PermitAddFriend(string friendname)

     {

         string friendid = "";                 //好友的id

         Sql s0 = new Sql();

         SqlDataReader r0 = s0.GetReader("select userid from userinfo where username=

         '" + friendname + "'");

         if(r0.Read())                         //得到好友id

               friendid = r0["userid"].ToString();

         r0.Close();

         s0 = null;                            //清除连接

         //添加为好友

         s.ExecuteSql("insert friend (type,userid,othername)values(0," + friendid

         + ",'" + selfname  + "')", false);

         SqlDataReader r = s.GetReader("select id from friend where userid =" + selfid

         + " and othername = '" + friendname + "'");

         if(!r.HasRows)                     //自己未在对方的联系人列表中

         {

               r.Close();

               //把自己加到对方的陌生人中

               s.ExecuteSql("insert friend (type,userid,othername)values(2," + selfid

               + ",'" + friendname + "')");

         }

         else

               r.Close();                                   //关闭连接

         HttpContext context = HttpContext.Current;

          //构造消息字符串

         string msg = selfname + "  同意了您的好友请求<br/>";

         //接受者未在线,直接插入数据库;

         if(context.Cache[friendname] == null)

         {

              string insertstr = "insert msg(sendername,receivername,msg) values('";

              insertstr += ("qucha" + "','" + friendname + "','" + msg + "')");

              s.ExecuteSql(insertstr);                      //插入记录

         }

         else//在线,放入内存,等待接收

         {

              Msg mymsg = new Msg("qucha", msg);            //构造系统消息

              ((ChatUser)(context.Cache[friendname])).Message.Add(mymsg);

         }

     }

     //添加好友 第三步(2)拒绝被加为好友

     //friendname 被添加者的账号

     [WebMethod]

     public void RejectAddFriend(string friendname)

     {

         HttpContext context = HttpContext.Current;

         string msg = selfname + "  拒绝了您的好友请求<br/>";

         //接受者未在线,直接存入数据库;

         if(context.Cache[friendname] == null)

         {

              string insertstr = "insert msg(sendername,receivername,msg) values('";

              insertstr += ("qucha" + "','" + friendname + "','" + msg + "')");

              s.ExecuteSql(insertstr);                      //存入数据库

         }

         //在线,放入内存,等待接收。

         else

         {

              Msg mymsg = new Msg("qucha", msg);            //系统消息

              ((ChatUser)(context.Cache[friendname])).Message.Add(mymsg);

         }

     }

     #endregion

18.5.3  获取聊天记录

GroupMsgHistory() 和MsgHistory()方法分别用来获取群聊天和两人聊天的聊天记录。无论群聊天还是两人聊天,最新的聊天记录都保存在Cache中。所以,获取聊天记录时,首先需要从Cache中获得聊天记录。然后再从数据库中获取聊天记录,最后将两者进行组合发送给用户。获取聊天记录的相关程序代码如下:

#region 聊天记录

      // 获取群聊天的记录

      // groupid  群号

      [WebMethod]

      public DataView GroupMsgHistory(string groupid)

      {

           Sql sql = new Sql();

           DataSet ds;

           string s = "select sendername,sendtime,msg from  groupmsg where groupid

           = " + groupid + "";

           HttpContext context = HttpContext.Current;

           ds = sql.getMyDataSet(s);                   //得到数据库中本群的所有消息

           if(context.Cache["$" + groupid] != null)     //如果cache中还存在本群的消息

           {

                MyGroup gmt = (MyGroup)(context.Cache["$" + groupid]);

                for(int i = 0; i < gmt.List.Count; i++) //遍历cache中本群的每条聊天记录

                {

                     BaseMsg bm = (BaseMsg)(gmt.List[i]);

                     //把记录添加到返回的数据中

                     ds.Tables[0].Rows.Add(new object[] { bm.SenderName, bm.SendTime,

                     bm.Message });

               }

           }

           ds.Tables[0].DefaultView.Sort = "sendtime desc";//数据按发送时间进行排序

           return ds.Tables[0].DefaultView;

      }

      // 获取两人聊天的记录

      //othername  和自己聊天者的name 

      [WebMethod]

      public DataView MsgHistory(string othername)

      {

           Sql sql = new Sql();

           DataSet ds;                             //聊天的记录集

           string s = "select sendername,sendtime,msg,receivername from  msg where

           (sendername= '"+ selfname + "' and receivername = '" + othername + "')

           or (sendername='" + othername + "' and receivername='" + selfname + "')";

           ds = sql.getMyDataSet(s);               //得到数据库中需要的所有的数据

           if(HttpContext.Current.Cache[selfname] != null)    //自己的内存块中存有数据

           {

                MsgTable gmt = ((ChatUser)(HttpContext.Current.Cache[selfname])).

                Message;

                //遍历每条数据,把符合条件的数据添加到返回的数据集合中

                for(int i = 0; i < gmt.List.Count; i++)

                {

                     Msg bm = (Msg)(gmt.List[i]);

                     if(bm.SenderName == othername)   //符合条件

                         ds.Tables[0].Rows.Add(new object[] { bm.SenderName, bm.Send

                         Time, bm.Message, selfname });

                }

           }

           if(HttpContext.Current.Cache[othername] != null)//聊天对方的内存块中存有数据

           {

                //遍历每条数据,把符合条件的数据添加到返回的数据集合中

                MsgTable gmt = ((ChatUser)(HttpContext.Current.Cache[othername])).

                Message;

                for(int i = 0; i < gmt.List.Count; i++)

                {

                     Msg bm = (Msg)(gmt.List[i]);

                     if(bm.SenderName == selfname)        //符合条件,添加数据

                         ds.Tables[0].Rows.Add(new object[] { bm.SenderName, bm.

                         SendTime, bm.Message, othername });

                }

           }

           ds.Tables[0].DefaultView.Sort = "sendtime desc";            //数据排序

           return ds.Tables[0].DefaultView;

       }

       #endregion

18.5.4  其他代码

除了上面介绍的程序代码外,Web服务层还包括其他一些功能代码。例如,登录,增、删黑名单,接收系统消息、判断某人是否给自己发送了最新消息等。具体实现代码如下:

using System;

using System.Web;

using System.Collections;

using System.Web.Services;

using System.Web.Services.Protocols;

using System.Collections.Generic;

using System.Text;

using System.Data;

using System.Data.SqlClient;

namespace MyChat

{

    // 聊天程序web服务

    [WebService(Namespace = "http://www.qucha.net/")]

    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

    public class improve : System.Web.Services.WebService

    {

         Sql s = new Sql();                                    //数据库操作类

         int selfid=0;                                         //用户id

         string selfname="";                                   //用户名

         public improve()

         {

              //初始化各种变量

              if(User.Identity.IsAuthenticated)                 //用户已经登录

              {

                   selfname = User.Identity.Name;            //给name赋值

                   selfid = int.Parse(tools.GetUserId(selfname)); //给id赋值

              }

         }

         // 登录 ,返回0操作失败,返回1操作成功,返回2密码错误

         [WebMethod]

         public int Login(string username, string pass)

         {

              int b = 0;                                        //登录成功与否的标志

              int userid = 1;

              pass = tools.Encrypt(pass, "12345678");           //密码加密

              //获取用户id

              SqlDataReader r = s.GetReader("select userid,pass from userinfo where

              username='" + username + "'");

              if(r.Read() && r[1].ToString() != pass) //如果存在这个用户,但密码错误

              {

                   r.Close();                        //关闭连接

                   return 2;                         //返回2

              }

              else if (r.HasRows == false)  //不存在这个用户,则在数据库中存入这个用户

              {

                   r.Close();                        //关闭连接

                   s.ExecuteSql("insert userinfo(pass,username) values ('" + pass +

                   "','" + username + "')", false);

                   //重新获取此用户的id

                  r = s.GetReader("select userid from userinfo where username='" +

                  username + "'");

                   r.Read();

              }

              userid = int.Parse(r[0].ToString());  //获取用户id

              //登录

              System.Web.Security.FormsAuthentication.RedirectFromLoginPage(username,

              false );

             selfid = userid;                       //用户id

             selfname = username;                   //用户name

               try

               {

                   //初始化一个聊天用户类

                   MyChat.tools.AddNewUser(HttpContext.Current) ;

                   b = 1;                        //操作成功完成

                   tools.UpdateSelfTime();           //更新自己的过期时间

               }

               catch

               { }

               return b;

          }

          // 删除好友

          //friendname 好友的账号

          [WebMethod]

          public void DelFriend(string friendname)

          {

               string userid = tools.GetUserId(User.Identity.Name); //自己的id

               //删除

               s.ExecuteSql("delete from friend where userid =" + userid + " and

               othername = '" + friendname + "' type =0");

          }

          #region 添加删除黑名单的操作

          //添加黑名单

          [WebMethod]

          public void AddBlack(string blackname, string blackid)

          {       

               //如果此用户在两个人的联系人名单中,删除这些信息

               s.ExecuteSql("delete from friend where userid =" + selfid + " and

               othername = '" + blackname + "'", false);

               s.ExecuteSql("delete from friend where userid =" + blackid + " and

               othername = '" + selfname + "'", false);

               //插入黑名单

               s.ExecuteSql("insert friend (type,userid,othername)values(1," +

               selfid.ToString() + ",'" + blackname + "')");

          }

          //删除黑名单

          [WebMethod]

          public void DelBlack(string blackname)

          {

               s.ExecuteSql("delete from friend where userid =" + selfid.ToString()

               + " and othername = '" + blackname + "' type =1");    //删除

          }

          #endregion

          // 判断特定用户是否给自己发送了新消息

          //sn发送者姓名

          //返回ture有新消息

          public bool CheckMessage(string sn)

          {

               bool b = false;

               string temp = "0";                   //内存中存在的聊天记录id 的字符串

               ChatUser my = (ChatUser)(HttpContext.Current.Cache[selfname]);

               if(my == null)                       //没有聊天用户类,初始化一个

               {

                   tools.AddNewUser(HttpContext.Current);

                   my = (ChatUser)(HttpContext.Current.Cache[selfname]);

               }

               //遍历自己的消息表,判断是否存在某用户的未读消息

               for(int i = 0; i < my.Message.List.Count; i++)

               {

                   //存在这样的消息

                   if(((Msg)(my.Message.List[i])).SenderName == sn && ((Msg)(my.

                   Message.List[i])).IfRead == false)

                   {

                        b = true;

                        return b;                  //存在消息返回

                   }

                   temp += ("," + i);            //记录下已经处理的消息id

               }

               if(my.Message.HaveOtherMsg == true)  //如果数据库中还有数据

               {

                   Sql q = new Sql();

                   //读取所有符合条件的数据

                   SqlDataReader reader = q.GetReader("Select [id] From  msg  Where

                   [receivername] ='"+ selfname + "' and sendername='" + sn + "' and

                   ifread=1 and id not in (" + temp + ") ");

                   //有新消息

                   if(reader.HasRows)

                   {

                        b = true;

                   }

                   reader.Close();

               }

               return b;

          }

          // 得到特定用户的系统消息总数

          public int GetSysMsgNum()

          {

               int b = 0;

               string temp = "0";                   //内存中存在的聊天记录id 字符串

               ChatUser my = (ChatUser)(HttpContext.Current.Cache[selfname]);

               if(my == null)                       //聊天用户类不存在,初始化一个

               {

                   tools.AddNewUser(HttpContext.Current);

                   my = (ChatUser)(HttpContext.Current.Cache[selfname]);

               }

               //遍历所有数据,查询qucha发送的数据(即系统消息)

               for(int i = 0; i < my.Message.List.Count; i++)

               {

                   if(((Msg)(my.Message.List[i])).SenderName == "qucha" && ((Msg)

                   (my.Message.List[i])).IfRead == false)

                   {

                         b++;                      //找到一条记录,数目加1

                   }

                   temp += ("," + i);

               }

               //数据库中还有其他数据

               if(my.Message.HaveOtherMsg == true)

               {

                    Sql q = new Sql();

                    //取数据

                    DataSet ds = q.getMyDataSet("Select [id] From  msg  Where

                    [receivername] ='"+ selfname + "' and sendername='" + "qucha" +

                    "' and ifread=1 and id not in (" + temp + ") ");

                    b += ds.Tables[0].Rows.Count;     //把数目加上

               }

               return b;

          }

     }

}

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论