2011-07-27 20 views
0

我有一個頁面,其中發生了大量耗時的功能。我想要做的是在該過程的每個步驟完成後,更新網頁以讓用戶知道剛剛完成的步驟。實質上,用戶提交查詢,然後服務器查詢數據庫,處理數據,繪製圖像並在頁面上顯示結果。我想讓網頁說明該功能在哪一步。它會說,「查詢」,然後是「處理」等。將網頁更新爲過程運行

僞:

protected void Search(object sender, EventArgs e){ 

    //display that the process has begun 
    List queryResults = Query() 
    //display that the query is finished 
    foreach(item in queryResults){ 
     ProcessItem(item) 
     //display that item has been processed 
     Render(item) 
     //display item has been rendered 
    } 

} 

我已經調查使用Ajax無需重新加載它來更新頁面,但是從我簡單的理解(阿賈克斯零經驗),客戶端將被從服務器請求一個文件。 Ajax是我需要的工具嗎?如果是這樣,這是否意味着在評論區域中,我會向客戶端發送ajax響應?

回答

0

Web服務器不能向客戶端推送未經請求的數據;他們服從請求 - 響應週期。另一種方法是使用消息隊列來顯着增加複雜性。

來自客戶的投票並不是那麼糟; Web服務器擅長處理很多短的請求,並且2或3秒的輪詢間隔應該足夠快。

這是我喜歡使用的輪詢方法。它異步地等待響應再來投票前回(需要的jQuery):

function poll(url, task, progressBar, resultsCallback, 
     timeoutMillis, pollIntervalMillis) { 
    $.ajax({ 
     url: url, 
     type: 'GET', 
     dataType: 'json', 
     timeout: timeoutMillis, 
     data: 'action=poll&task='+task, 
     success: (function(response, status, xhr) { 
      if ('progress' in response) { 

       // update the UI with the progress 
       progressBar.setValue(response.progress); 
      } 
      if ('status' in response) { 
       if (response.status == 'pending') { 

        // task is not finished, continue polling 
        setTimeout((function() { 
         poll(url, task, progressBar, resultsCallback, 
           timeoutMillis, pollIntervalMillis); 
        }), pollIntervalMillis); 
       } 
       else { 

        // task completed 
        if (response.status == 'cancelled') { 
         progressBar.setColor('red'); 
         progressBar.setText("Task '"+task+"' was cancelled"); 
        } 
        else { 
         progressBar.setColor('green'); 
         progressBar.setText("Task '"+task+"' complete"); 
        } 

        // GET the results 
        $.ajax({ 
         url: url, 
         type: 'GET', 
         timeout: timeoutMillis, 
         data: 'action=results&task='+task, 
         success: (function(response, status, xhr) { 
          resultsCallback(response, status, xhr); 
         }), 
         error: error 
        }); 
       } 
      } 
     }), 
     error: error 
    }); 

    function error(xhr, status, err) { 
     alert('Failure to communicate with server: ' + status + ', ' + err); 
    } 
} 

你的服務器端代碼應該響應民調是這樣的:

{"progress" : 42, "status" : "pending"} 
0

如果您是通過AJAX完成的,您需要讓客戶端JavaScript在頻率上執行ajax請求,以確定狀態是否已更新。另一種選擇是在客戶端使用silverlight,它能夠進行更強大的事件驅動的會話。

兩者都是可行和不錯的選擇。

這裏的Silverlight + WCF的一般入門空間: http://www.silverlight.net/learn/advanced-techniques/wcf-ria-services/get-started-with-wcf-ria-services

+0

你能否詳細說明或在這方面指導我一個很好的來源?我寧願不讓客戶端經常ping服務器,詢問是否完成了一個步驟。我寧願讓服務器在每個步驟結束時向客戶端發送消息。 – spots

+0

@pot添加編輯 –

0

以一定的間隔一個Ajax請求輪詢是最常見的選擇,或者你可以關閉HTTP響應的緩衝和流狀態更新回到一個單一的http請求中的客戶端。如果這是一項長時間運行的操作,則需要在後一種情況下仔細考慮用戶體驗和可伸縮性。

Html 5 WebSockets也將解決這個特定的情況。不過,我不確定這些HTML5兼容瀏覽器當前的狀態。

+0

服務器上的一個開放套接字也沒有保證客戶端超時規則,考慮到網絡瀏覽器和網絡/代理/防火牆的變化 –