web页面即时通讯简单原型

3 篇文章 0 订阅
1 篇文章 0 订阅

基于web 的应用程序的工作方式。使用客户端从服务器端获取一持续的信息主要有两种方式。
一是http长连接,很长时间以来,国内外的程序员都在对web服务如何实现长连接推送进行研究,但一直进展缓慢,这主要是由于两方法的原因造成的。首先一般的web服务器都不是针对TCP/IP长连接进行优化设计的,长连接会造成服务器端资源消耗过快,维持http的长连接的服务器资源成本过高。其次,浏览器的设计通常也不是基于长连接进设计的。例如对于IE6来说,IE浏览器维持的http连接数非常少。长期占用一个连接是非常浪费客户端资源的。所以推送并不是一个web应用应当采取的合适的方案。
第二种就是轮询,轮询的有两种实现方式,一种是页面定时提交方式,这种方案多出现于更早期的利用js和iframe进行数据获取的情况下。另一种就是目前已经渐渐成熟的利用Ajax技术和Web Services进行数据获取和页面展示的方法了。这也是我们着重要探讨的方法。
AJAX即“Asynchronous JavaScript and XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。该技术在1998年前后得到了应用。允许客户端脚本发送HTTP请求(XMLHTTP)的第一个组件由Outlook Web Access小组写成。该组件原属于微软Exchange Server,并且迅速地成为了Internet Explorer 4.0的一部分。部分观察家认为,Outlook Web Access是第一个应用了Ajax技术的成功的商业应用程序,并成为包括Oddpost的网络邮件产品在内的许多产品的领头羊。自2005年初开始,Ajax开始被大众所接受。Google在它著名的交互应用程序中使用了异步通讯,如Google讨论组、Google地图、Google搜索框架应用等。
AJAX主要由以下的几种技术实现:
基于web标准(standards-based presentation)XHTML+CSS的表示;使用 DOM(Document Object Model)进行动态显示及交互;使用 XML 和 XSLT 进行数据交换及相关操作;使用 XMLHttpRequest 进行异步数据查询、检索;使用 JavaScript 将所有的东西绑定在一起。
而Web Services是由企业发布的完成其特定商务需求的在线应用服务,其他公司或应用软件能够通过Internet来访问并使用这项在线服务。是一种构建应用程序的普遍模型,可以在任何支持网络通信的操作系统中实施运行;同时它也是一种新的web应用程序分支,是自包含、自描述、模块化的应用,可以发布、定位、并通过web进行调用。其架构如图1所示。
Web Service是一个应用组件,它逻辑性的为其他应用程序提供数据与服务.各应用程序通过网络协议和规定的一些标准数据格式(Http,XML,Soap)来访问Web Service,通过Web Service内部执行得到所需结果。Web Service可以执行从简单的请求到复杂商务处理的任何功能。一旦部署以后,其他Web Service应用程序可以发现并调用它部署的服务。

下面我们就如何使用这一种方式,基于.net 2.0进行一个简单的web 即时通讯系统的设计进行一个简单的介绍。
首先,我们在Global.asax中新建一个类

public class TheGlobalMsgs
{
 const long timerDelay = 60000;
 //定时器过期时间秒(1分钟内的短消息保留)
 //客户端最长每秒一取!
 Timer theTimer;
 public static DataTable theMsgsTable = null;
 public TheGlobalMsgs()
 {
  theMsgsTable = new DataTable("TheMsgTable");
  //建立内存表, 表名:"TheMsgsTable"
  //建立msgText、GetUserID、SendUserID、SendUserID SendUserName、SendTime字段
  System.Data.DataColumn Column2=new DataColumn("msgText",typeof(System.String));
  …
  theMsgsTable.Columns.Add(Column2);
  …
TimerCallback OnTimerTick = new TimerCallback(TimerTick);
  theTimer=new Timer(OnTimerTick,null,timerDelay,timerDelay);
 }
 // 定时期过期方法删除表中的两分钟以前的过期值
 private void TimerTick(object state)
 {
  DataView theDV = new DataView(theMsgsTable);
  theDV.AllowDelete=theDV.AllowEdit=theDV.AllowNew=true;
  theDV.RowFilter = "SendTime < #"
    +DateTime.Now.AddMilliseconds(-120000).ToLongTimeString()
    +"#";
  for(int i=0;i<theDV.Count;i++)
  {theDV.Delete(i);}
  theMsgsTable.AcceptChanges();
 }
 // 向内存表中添加一个消息
 public bool AddMsg(string inp_SendUser_ID,string inp_SendUser_Name,string inp_GetUser_ID,string inp_TheMsgText)
 {
  if(inp_GetUser_ID==null
    || inp_GetUser_ID == ""
    || !DAL.DBBase.IsInt(inp_GetUser_ID)
    || inp_TheMsgText == null
    || inp_TheMsgText == "")
   return false;
  if (inp_SendUser_ID != null && inp_SendUser_ID != "")
   if (!DAL.DBBase.IsInt(inp_SendUser_ID))
    return false;
  System.Data.DataRow theRow = theMsgsTable.NewRow();     //新行;
  theRow["msgText"] = inp_TheMsgText;      //发送内容;
  …
  theMsgsTable.Rows.Add(theRow);    // 将该行数据添加进表
  theMsgsTable.AcceptChanges();
  return true;
 }
 // 得到发给某人的短消息
 public DataTable GetSomeBodyMsgs(string inp_GetUser_ID)
 {
  DataTable theBackTable = null;
  if (inp_GetUser_ID != null
    && inp_GetUser_ID != ""
    && DAL.DBBase.IsInt(inp_GetUser_ID))
  {
   DataView theDV = new DataView(theMsgsTable);
   theDV.AllowDelete=theDV.AllowEdit=theDV.AllowNew=true;
   theDV.RowFilter="GetUserID="+inp_GetUser_ID;
   theDV.Sort="SendTime";
   theBackTable=theDV.ToTable();//从视图中取值
   for(int i=0;i<theDV.Count;i++)
   {
    theDV.Delete(i);
   }
   theMsgsTable.AcceptChanges();
  }
  return theBackTable;
}
由以上代码中可以看到,类的构造方法中创建了一个记录当前系统中传递信息的内存表用于,记录用户之间发送的信息,接收方的ID,发送方的ID,发送方的名称和发送时间。并提供了三个对应的方法AddMsg,GetSomeBodyMsgs,TimerTick方法。分别对于添加信息,获取信息和清除过期信息。
其中AddMsg是向内存表中添加一条记录,记录相应的发送的信息,接收方的ID,发送方的ID,发送方的名称和发送时间,用于用户A向用户B发送信息时调用。
GetSomeBodyMsgs是从内存表中提取所有某用户要接收的信息记录,并在提取后删除,用于用户B提取自己在一次轮询中获取其他用户发给自己的信息。
TimerTick是从内存表中定期清除发送时间超出规定时间的信息。这些信息就是用户发送后无人来接收的信息。由此我们就完成了一个信息互通必要的几个功能了。
下面我们使用这一个类来搭建一个webservice
首先我们在Global.asax中的Application_Start方法中实例化这个类

protected void Application_Start(object sender, EventArgs e)
{
 //创建站点短消息类用于定时轮询!
 Application["TheGlobalMsg"]=new TheGlobalMsgs();
}

然后我们创建一个webService页面user_msg_WebService.asmx提供给用户用以调用这一方法的接口。

// user_msg_WebService 的摘要说明
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public class user_msg_WebService : System.Web.Services.WebService
{
 //GetSomeBodyMsgs 得到某用户消息
 [WebMethod(EnableSession = true)]
 public DataTable GetSomeBodyMsgs()
 {
  BLL.TheUser theLoginUser = (BLL.TheUser)Context.Session["the_User"];
  return ((TheGlobalMsgs)Application["TheGlobalMsg"]).GetSomeBodyMsgs(theLoginUser.USER_ID);
 }
 // AddMsgs 添加一个消息
 [WebMethod(EnableSession = true)]
 public bool AddMsgs(string inp_GetUser_ID,string inp_TheMsgText)
 {
  BLL.TheUser theLoginUser = (BLL.TheUser)Context.Session["the_User"];
  return ((TheGlobalMsgs)Application["TheGlobalMsg"]).AddMsg(theLoginUser.USER_ID, theLoginUser.TRUE_NAME, inp_GetUser_ID, inp_TheMsgText);
  }
 }
}

这样我们就可能在一个页面中通过JS使用Ajax来定时获取某用户的信息。JS的实现方法如下。

function DocTimer()
{
 var ajax = new Ajax(
  "user_msg_WebService.asmx/GetSomeBodyMsgs",
  "","POST",function (req)
  {
   //回调函数
   var doc_el = req.responseXML.documentElement;
   var i=0;
   var SendUserName = "";
   var msgText = "";
   do
   {
    SendUserName="";
    SendUserName = get_element (doc_el, "SendUserName", i);
    msgText =  get_element (doc_el, "msgText", i);
    if(SendUserName!=null && SendUserName!="")
     ShowMsg("注意",200,120,"短消息提示:","您有一条消息",msgText,"_self","");
    i++;
   }while(SendUserName!=null && SendUserName!="")
   });
 ajax.request ();
 setTimeout("DocTimer()",10000);
}


同理我们也可以调用webService中的AddMsg方法来利用Ajax向系统中的其他用户发送消息。这样一个完整的基于web的即时通讯系统的内核就设计好了。再进行一些UI,容错方面的考虑就可以正式使用了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值