【问题标题】:Update a Web Page as a Process Runs在进程运行时更新网页
【发布时间】:2011-10-14 12:31:51
【问题描述】:

我有一个页面,其中出现了许多耗时的功能。我想做的是随着流程的每个步骤完成,更新网页让用户知道刚刚完成了什么步骤。本质上,用户提交查询,然后服务器查询数据库、处理数据、绘制图像并在页面上显示结果。我希望网页说明该功能在哪一步。它会说,“查询”然后“处理”......等等。

伪:

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 是我需要的工具吗?如果是这样,这是否意味着在评论区我会向客户端发送一个 ajax 响应?

【问题讨论】:

    标签: c# html ajax


    【解决方案1】:

    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"}
    

    【讨论】:

      【解决方案2】:

      定期轮询 ajax 请求是最常见的选项,或者您可以关闭 http 响应的缓冲并将状态更新流式传输回客户端,所有这些都在单个 http 请求中完成。如果这是一项长期运行的操作,您需要在后一种情况下仔细考虑用户体验和可扩展性。

      Html 5 WebSockets 也将解决这个特定的场景。但是,我不确定这些在当前兼容 Html 5 的浏览器中处于什么状态。

      【讨论】:

      • 考虑到 Web 浏览器和网络/代理/防火墙的多样性,服务器上打开的套接字也没有保证客户端超时规则
      【解决方案3】:

      如果您使用 AJAX 执行此操作,则需要让客户端 javascript 以一定频率执行 ajax 请求以查明状态是否已更新。另一种选择是在客户端使用 silverlight,它能够进行更强大的事件驱动对话。

      两者都是可行且不错的选择。

      这是silverlight+wcf 的一般入门空间: http://www.silverlight.net/learn/advanced-techniques/wcf-ria-services/get-started-with-wcf-ria-services

      【讨论】:

      • 你能详细说明或指导我找到一个好的来源吗?我宁愿不要让客户端不断地 ping 服务器来询问是否完成了某个步骤。我宁愿让服务器在每一步结束时向客户端发送一条消息。
      猜你喜欢
      • 2015-11-24
      • 1970-01-01
      • 2021-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多