c#如何使用webservice、存储过程及存储过程的创建(简单模仿类似QQ统计用户在线时间为例)...

本文介绍了一个使用WebService和Oracle数据库统计用户在线时间的应用案例。通过客户端与服务器端交互,记录用户的启动和停止时间,实现对用户使用时长的精确统计。

   在这个小应用中,要用到webservice,因此简单介绍一下webservice。在实际应用中从客户端传送信息至服务端,使用webservice是一个不错的方法,它是一种构建应用程序的普遍模型,可以在任何支持网络通信的操作系统中实施运行。NET平台内也建立了对Web Service的支持,包括Web Service的构建和使用。NET Framework本身就全面支持Web Service,包括服务器端的请求处理器和对客户端发送和接受SOAP消息的支持。因此不需要其他的工具或者SDK就可以完成Web Service的开发了。

    那么下面我们看看如何在服务器统计用户的在线时间。

环境:visual studio 2008;.net framework 2.0;Oracle 10g

功能实现:有两个表usertable a,userinfotable b, a存放用户基本固有信息,b表存放用户使详细信息及时间。当用户上线时程序中的webservice上传一次用户启动时间,当用户下线程序中webservice再次发送用户停止使用时间,进行保存,记录了一次用户使用时间,方便进行后续处理。

设计过程如下:

一、数据库设计

 1、设计数据表

usertable
字段类型说明
idinteger表id,自增序列,主键
usersequencevarchar2(100)用户QQ号码,非空,唯一
uipvarcha2r(50)用户ip地址,从客户端获取
uaddressvarchar2(100)用户所在地址,从客户端根据ip获取
usystemvarcar2(32)用户使用的操作系统的位数,从客户端获取
useraddtimedate用户注册时间,也就是第一次插入数据的时间
   

userinfotable
字段类型说明
id integer表id,自增序列,主键
consumeridinteger用户id,外键,usertable表userid关联
ustarttimedate用户本次启动软件时间
uendtimedate用户本次关闭软件时间
usertotaltimesinteger用户使用累计时间
useraddtimedate用户最后一次使用时间

2、详细SQL

(1)、创建表,序列

create table usertable  (    id       INTEGER not null,    usersequence      varchar2(100),    uip       varchar2(50),    uaddress VARCHAR2(100),    usystem VARCHAR2(32),    useraddtime date  )  create table userinfotable  (    id  INTEGER not null,    consumerid INTEGER,    ustarttime   date,    uendtime date,    usertotaltimes number(30),    useraddtime date  )  CREATE SEQUENCE  USERTABLE_SEQUENCES       INCREMENT BY 1    START WITH 1     MAXVALUE   9999999999999999999  CREATE SEQUENCE USERINFOTABLE_SEQUENCES       INCREMENT BY 1    START WITH 1     MAXVALUE   9999999999999999999

(2)、存储过程

开启qq时发送信息的存储过程

create or replace procedure startqqprocedure  (qq in varchar2,ip in varchar2,address in varchar2,systemname in varchar2)   as    userid  number;     infoid  number;    begin      select count(a.id) into userid from usertable a where a.usersequence=qq;       if userid >0        then         update usertable a set a.uip =ip,a.uaddress=address,a.usystem=systemname where a.usersequence = qq;        else         select usertable_sequences.nextval into userid from dual;         insert into usertable (id,usersequence,uip,uaddress,usystem,useraddtime)          values(userid,qq,ip,address,systemname,sysdate);       end if;         insert into userinfotable(id,consumerid,ustarttime,uendtime,usertotaltimes,useraddtime)         values(userinfotable_sequences.nextval,userid,sysdate,sysdate,0,sysdate);  commit;   exception  when others then  rollback;  end startqqprocedure;

关闭qq时发送信息的存储过程

create or replace procedure closeqqprocedure  (qq in varchar2,ip in varchar2,address in varchar2,systemname in varchar2)    as    userid   number;    begin     select count(a.id) into userid  from usertable a where a.usersequence=qq;     if userid >0       then          update usertable a set a.uip =ip,a.uaddress=address,a.usystem=systemname where a.usersequence = qq;     else         select usertable_sequences.nextval into userid from dual;         insert into usertable (id,usersequence,uip,uaddress,usystem,useraddtime)          values(userid,qq,ip,address,systemname,sysdate);              insert into userinfotable(id,consumerid,ustarttime,uendtime,usertotaltimes,useraddtime)       values(userinfotable_sequences.nextval,userid,sysdate,sysdate,0,sysdate);       end if;              update userinfotable c set c.uendtime=sysdate,c.usertotaltimes= round(c.usertotaltimes)+       round(to_number(sysdate-c.ustarttime)*1440)where c.consumerid = userid;   commit;   exception  when others then  rollback;  end closeqqprocedure;

二、代码实现
1、服务器端webservice实现。
数据库部分已完成,下面来进行程序实现,使用MVC设计模式,初步订三个类,webservice,DAO层QQWebServiceDao,执行sql语句SDProvider,实现各功能分离。
看看webservice如何写。

using System.Web;  using System.Web.Services;  using System.Web.Services.Protocols;  using QQWebApp.WebWork.Dao;    namespace QQWebApp.Service  {      /// <summary>      /// LMWebService 的摘要说明      /// </summary>      [WebService(Namespace = "QQWebservice")]      [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]      [ToolboxItem(false)]      public class QQWebservice: System.Web.Services.WebService      {          [WebMethod]          //启动软件后          public bool FirstStart(string qq, string ip, string address,string systemname)          {              bool result = false;                result = QQWebServiceDao.UploadStartCloseSoftInfo(qq, ip, address, systemname,true);                return result;          }          [WebMethod]          //关闭软件          public bool EndStop(string qq, string ip, string address,string systemname)          {              bool result = false;                result = QQWebServiceDao.UploadStartCloseSoftInfo(qq, ip, address, systemname,false);                return result;          }  }

那么c#如何执行存储过程呢?写数据库执行类,包括数据库连接,执行sql。

using System.Data;  using System.Configuration;    using System.Collections.Generic;  using System.Data.OracleClient;  using System.Diagnostics;  using System;    namespace QQWebApp.WebWork.Data  {      public class SDProvider      {          public static string GetConnectionString()          {              string conStr = "User ID=qqsoft;data source=orcl;password=sys";              return conStr ;          }                   public static int RunProcedure(string storedProcName, IDataParameter[] parameters)          {              int result = 0;                try              {                  using (OracleConnection connection = new OracleConnection(GetConnectionString()))                  {                      connection.Open();                        OracleCommand command = BuildQueryCommand(connection, storedProcName, parameters);                        result = command.ExecuteNonQuery();//返回受影响的行数                  }              }              catch (Exception e)              {                  Debug.Assert(false, e.Message);              }                return result;          }          private static OracleCommand BuildQueryCommand(OracleConnection connection, string storedProcName,              IDataParameter[] parameters)          {              OracleCommand command = new OracleCommand(storedProcName, connection);                command.CommandType = CommandType.StoredProcedure;                foreach (OracleParameter parameter in parameters)              {                  command.Parameters.Add(parameter);              }              return command;          }  }

这个类完成了存储过程的执行,参数的传递。
下面可以开始写DAO层,该层负责参数的处理,并调用SDProvider执行存储过程。

using System;  using System.Data;  using System.Configuration;  using System.Web;  using System.Web.Security;  using System.Web.UI;  using System.Web.UI.HtmlControls;  using System.Web.UI.WebControls;  using System.Web.UI.WebControls.WebParts;  using QQWebApp.WebWork.Data;  using System.Data.OracleClient;    namespace QQWebApp.WebWork.Dao    public class QQWebServiceDao   {    public static bool UploadStartCloseSoftInfo(string qq, string ip,string address,string systemname,bool flag)     {           int result = 0;                      OracleParameter qqParameter = new OracleParameter("qq", OracleType.VarChar, 100);                    qqParameter.Value = qq;                      OracleParameter ipParameter = new OracleParameter("ip", OracleType.VarChar, 100);                    ipParameter.Value = ip;                       OracleParameter addressParameter = new OracleParameter("address", OracleType.VarChar, 100);                    addressParameter.Value = address;                       OracleParameter systemnameParameter = new OracleParameter("systemname", OracleType.VarChar, 100);                    systemnameParameter.Value = systemname;                       OracleParameter[] parameter = { qqParameter, ipParameter, addressParameter, systemnameParameter };                       if (flag)          {            result = SDProvider.RunProcedure("startqqprocedure", parameter);          }          else          {          result = SDProvider.RunProcedure("closeqqprocedure", parameter);          }                       return result > 0 ? true : false;              }      }  }

这样就完成了服务端的程序。webservice、存储过程实现了融合使用。在这部分有几点注意的地方。
(1)、写存储过程中,定义的参数是不需要定义长度的。在存储过程中声明的变量不用加in|out。
(2)、DAO层中GetConnectionString()获取数据库的连接,这个连接字符串可以通过加密存放在Web.config中,更安全一些。
2、客户端调用
这样客户端的调用就很简单,首先要添加刚才写好的webservice,webservice写好发布之后有一个地址,假设是:http://testQQ.WebService/QQWebService.asmx,在本地添加引用。
声明并实例化,
 TestQQ.QQWebService service = new TestQQ.QQWebService ();
就可以调用service.看到FirstStart和endstop方法。不过在客户端还有一个任务,就是获取客户端的ip,省市地址和所使用的系统。获取ip参见http://blog.youkuaiyun.com/yysyangyangyangshan/article/details/6803787,获取省市参见http://blog.youkuaiyun.com/yysyangyangyangshan/article/details/6773815,获取使用的系统是32还是64位如下:

public class OSDetectQuery   {          public static string QueryOSVersion()          {              try              {                  ConnectionOptions oConn = new ConnectionOptions();                  System.Management.ManagementScope oMs = new System.Management.ManagementScope("\\\\localhost", oConn);                  System.Management.ObjectQuery oQuery = new System.Management.ObjectQuery("select AddressWidth from Win32_Processor");                  ManagementObjectSearcher oSearcher = new ManagementObjectSearcher(oMs, oQuery);                  ManagementObjectCollection oReturnCollection = null;                  try                  {                      oReturnCollection = oSearcher.Get();                  }                  catch (System.Exception ex)                  {                  }                    string addressWidth = null;                  foreach (ManagementObject oReturn in oReturnCollection)                  {                      addressWidth = oReturn["AddressWidth"].ToString();                  }                  return addressWidth;              }              catch (System.Exception ex)              {                  return "32";              }            }           public static string OsVersion()          {              string queryos = QueryOSVersion();                string osVersion = Environment.OSVersion.ToString();              if (osVersion.Equals("Microsoft Windows NT 6.1.7600.0"))              {                  if (queryos.Equals("64"))                  {                      return "Win7-64";                  }                    if (queryos .Equals("32"))                  {                      return "Win7-32";                  }                    return "Win7";              }              else if (osVersion.Equals("Microsoft Windows NT 6.1.7600.0"))              {                  if (queryos.Equals("64"))                  {                      return "Win7-64";                  }                    if (queryos.Equals("32"))                  {                      return "Win7-32";                  }                    return "Win7";              }              return "WinXP";            }      }

那么需要上传的客户端信息以获取完毕,直接调用service方法上传就可以了。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值