质疑贴——对《新版微软一站式示例代码库》中的一个示例的质疑

  在“新版微软一站式示例代码库发布 - 绑定第三版示例代码浏览器”中,有若干最新的asp.net的示例。

  对其中的一个示例的源代码研究了一番。觉得有问题,故在此阐述本人的疑问,望广大网友赐教。

  先把这个示例的说明贴在下方。

  CSASPNETReverseAJAX, VBASPNETReverseAJAX

  Downloads
  CSASPNETReverseAJAX: http://code.msdn.microsoft.com/CSASPNETReverseAJAX-7a1f0c2b
  VBASPNETReverseAJAX: http://code.msdn.microsoft.com/VBASPNETReverseAJAX-321a68b0

  反向Ajax又叫Comet模式Ajax, 推模式Ajax, 双向Web和 服务器推模式. 这种技术维护着一个HTTP请求来允许服务器向浏览器推送数据, 而不需要每隔一段特定的时间不断地向服务器提交请求. 这个示例演示了如何在ASP.NET Ajax里使用这种技术。

  

  按照上文的文字的理解。应该是浏览器这一端是被动方。而服务器这一端是主动方。服务器在获得消息的更新后,主动通知客户端更新消息的内容。如果是这样就太好了。可是看了源代码后,却发现貌似不是那么一回事。要么就是自己的理解上有问题。

  先看看各个文件的作用

  Sender.aspx                  客户端发送消息的页面

  Receiver.aspx                  客户端获得消息的页面

  Message.vb、ClientAdapter.vb、Client.vb    服务器端处理消息的类(采用单实例模式,有点像静态类)

  Dispatcher.asmx.vb               服务器端返回消息的WebService

 

  那么看看各个文件的关键部分的代码

  先看看Sender.aspx,客户端发送消息的页面

  Protected Sub btnSend_Click(ByVal sender As Object, ByVal e As EventArgs) 
    ' Create a message entity to contain all necessary data. 
    Dim message As New Message() 
    message.RecipientName = tbRecipientName.Text.Trim() 
    message.MessageContent = tbMessageContent.Text.Trim() 
 
    If Not String.IsNullOrWhiteSpace(message.RecipientName) AndAlso Not String.IsNullOrEmpty(message.MessageContent) Then 
      ' Call the client adapter to send the message to the particular recipient instantly. 
      ClientAdapter.Instance.SendMessage(message) 
 
      ' Display a timestamp. 
      lbNotification.Text += DateTime.Now.ToLongTimeString() & ": Message sent!<br/>" 
    End If 
  End Sub

  这个函数就是当“发送消息”按钮按下时,将客户端的消息写到后台的静态类中。

    

  Message.vb、ClientAdapter.vb、Client.vb这三个文件是后台的消息处理静态类,和本文的质疑无关。就不详细说了。

 

  再看看Dispatcher.asmx.vb,服务器端返回消息的WebService。它将合适的消息返回给调用者。

  <WebMethod()>Public Function WaitMessage(ByVal userName As String) As String 
    Return ClientAdapter.Instance.GetMessage(userName) 
  End Function

 

  最后看看Receiver.aspx,客户端获得消息的页面。它是如何获得后台即时消息的。

  Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As EventArgs) 
    ' Activate the JavaScript waiting loop. 
    If Session("userName") IsNot Nothing Then 
      Dim userName As String = DirectCast(Session("userName"), String) 
 
      ' Call JavaScript method waitEvent to start the wait loop. 
      ClientScript.RegisterStartupScript(Me.[GetType](), "ActivateWaitingLoop", "waitEvent();", True) 
 
      lbNotification.Text = String.Format("Your user name is <b>{0}</b>. It is waiting for new message now.", userName) 
 
      ' Disable the login. 
      tbUserName.Visible = False 
      btnLogin.Visible = False 
    End If 
  End Sub

  从这一段代码可以看出,在页面完成时,注册了一个JS代码,这个代码是waitEvent();

  我们看看这个页面的waitEvent()的代码,看看做了一些什么事。

  <script type="text/javascript"> 
    // This method will persist a http request and wait for messages. 
    function waitEvent() { 
 
      VBASPNETReverseAJAX.Dispatcher.WaitMessage("<%= Session("userName") %>",  
        function (result) {        
          displayMessage(result); 
           // Keep looping. 
          setTimeout(waitEvent, 0); 
        },

        function () { 
           // Keep looping. 
          setTimeout(waitEvent, 0); 
        }); 
      } 
 

    // Append a message content to the result panel. 
    function displayMessage(message) { 
      var panel = document.getElementById("<%= lbMessages.ClientID %>"); 
 
      panel.innerHTML += currentTime() + ": " + message + "<br />"; 
      } 
 
    // Return a current time string. 
    function currentTime() { 
      var currentDate = new Date() 
      return currentDate.getHours() + ":" + currentDate.getMinutes() + ":" + currentDate.getSeconds(); 
      } 
  </script>

 

  这一段的JS代码,是调用后台的WebService,将后台的消息显示到页面上。

  可是,为了达到“实时”的效果。它用了下面的一句话

  setTimeout(waitEvent, 0); 

  第二个参数是0,也就意味着是立即调用。

  通观整个waitEvent代码,实际上就是一个不停的调用后台的WebService,来获得消息。这似乎还是客户端是主动端,而且由于是一刻不停的调用后台的WebService,岂不是比间隔一段时间调用后台的WebService更加耗费资源吗?如果客户端只有一个还好,若是有成百上千的这样的客户端,那服务器岂不是负担很重?

 

  这是我看了源代码后的质疑。也许是哪儿我理解错了。望网友指正赐教。

 

时间: 2024-10-22 06:15:32

质疑贴——对《新版微软一站式示例代码库》中的一个示例的质疑的相关文章

微软一站式示例代码库

官方网站:http://1codechs.codeplex.com/ 这个下面有最受欢迎软件推荐下载和浏览示例代码KB以及C++, .NET 编码规范下载. 微软一站式示例代码库 中文官方博客 http://blog.csdn.net/mscodesample/article/details/7877255  

一款能在GitHub代码库中探测密钥的工具:Truffle Hog

工具简介 这款名叫"Truffle Hog"的免费开源工具可以帮助开发人员检测自己在GitHub上发布的项目代码是否意外泄漏了密钥. Truffle Hog是一款采用Python开发的工具,它可以检索GitHub代码库的所有代码提交记录以及分支,并搜索出可以表示密钥(例如AWS密钥)的高熵字符串. 运行机制 该工具的开发者Dylan Ayrey解释称: "Truffle Hog会检索代码库中每一个分支完整的代码提交记录,而且也会检查每一次提交的git diff信息,然后对每一

微软官方网站漏洞修复中存在一个补丁程序

近日,微软官方网站发布公告指出,12月漏洞修复中存在一个可能导致Outlook 2007出现故障的补丁程序,并建议已安装该补丁的用户尽快将其卸载,并通过官方产品博客向受影响的用户郑重道歉.12月22日,360安全中心宣布针对微软召回的补丁提供"一键自动修复"服务,帮助360用户快速.安全地卸载此补丁.据悉,大约有数百万中国电脑用户受到了微软召回补丁事件的影响.根据微软公告,用户电脑在安装编号为KB2412171的补丁后,可能导致Outlook 2007出现文件夹之间切换缓慢.自动存档功

程序代码-openssl中对一个字符串用md4加密

问题描述 openssl中对一个字符串用md4加密 给定一个字符串,如何把它转化成unsigned char类型.解决这个即可 解决方案 openssl直接命令行参数就可以

FileSystemObject 示例代码

filesystemobject|示例 在本节描述的示例代码,提供真实的例子来示范在 FileSystemObject 对象模式中可用的许多功能.该代码显示了如何一起使用对象模式的所有功能,以及如何在您自己的代码中有效地使用这些功能. 请注意,由于该代码是极一般的,所以要使该代码能够真正在您的机器上运行,可能需要一些其他代码和小小的变更.这些改变之所以必要,是因为在 Active Server Pages 和 Windows Scripting Host 之间,为输入和输出给用户采用了不同的方法

android电话窃听器(示例代码)_Android

在我上篇文章android短信监听工具(示例代码),开发了一个"短信监听工具",是基于广播接收者实现的,有一些缺陷(例如:不能隐藏的很深,不能开机自动运行...) 在本实例中,将使用新的技术"服务"来解决这些缺陷. 复制代码 代码如下: package cn.itcast.phone; import java.io.File;import java.io.OutputStream;import java.io.PushbackInputStream;import j

jQuery打印图片pdf、txt示例代码_jquery

html加如下代码 <div style="display:none"> <div id="to_print"></div> <input type="button" id="print_button" value="Print" onclick="document.getElementById('FILEtoPrint').focus(); docume

Android控件ListView用法(读取联系人示例代码)_Android

示例代码: 这是一个读取联系人的代码: 复制代码 代码如下: package com.ui.domain; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.database.Cursor; import android.database.DataSetObserver; import android.graphics.Color; import andro

Android控件ListView用法(读取联系人示例代码)

示例代码: 这是一个读取联系人的代码: 复制代码 代码如下: package com.ui.domain; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.database.Cursor; import android.database.DataSetObserver; import android.graphics.Color; import andro