天天看點

質疑貼——對《新版微軟一站式示例代碼庫》中的一個示例的質疑

  對其中的一個示例的源代碼研究了一番。覺得有問題,故在此闡述本人的疑問,望廣大網友賜教。

  先把這個示例的說明貼在下方。

  CSASPNETReverseAJAX, VBASPNETReverseAJAX

  Downloads 

  反向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 

  從這一段代碼可以看出,在頁面完成時,注冊了一個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. 

}); 

    // 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更加耗費資源嗎?如果用戶端隻有一個還好,若是有成百上千的這樣的用戶端,那伺服器豈不是負擔很重?

  這是我看了源代碼後的質疑。也許是哪兒我了解錯了。望網友指正賜教。

    本文轉自萬倉一黍部落格園部落格,原文連結:http://www.cnblogs.com/grenet/archive/2011/04/21/2023336.html,如需轉載請自行聯系原作者

繼續閱讀