使用ajax和webapi进行长时间轮询时的瘦身是什么......它会杀死我的服务器吗?和字符串比较

Chr*_*son 6 ajax long-polling asp.net-web-api

我有一个非常简单的长轮询ajax调用,如下所示:

(function poll(){
    $.ajax({ url: "myserver", success: function(data){
        //do my stuff here

    }, dataType: "json", complete: poll, timeout: 30000 });
})();
Run Code Online (Sandbox Code Playgroud)

我刚刚今天下午选了这个例子,看起来效果很好.我正在使用它在我的页面上构建一些html,它几乎是瞬间我尽力而为.我有点担心,这会让我的服务器上的工作线程保持打开状态,如果我在服务器上有太大的负载,它就会完全停止.有人能否对这一理论有所了解?在后端我有一个webapi服务(.net mvc 4),它调用数据库,构建对象,然后将对象传回.在我看来,为了使这个工作,服务器将不得不不断地调用数据库...这可能是不对的???

我的下一个问题是客户端确定是否需要更新页面上的html的最佳方法是什么?目前我正在使用JSON.stringify()将我的对象转换为字符串并比较字符串和旧字符串,如果有一个delta,它会在页面上重写html.现在不是一个整体在对象下降很多,但它可能会变得非常大,我认为进行字符串比较可能在客户端上非常耗费资源......特别是如果它几乎不断地进行.

对我来说,底线是这样的:我不确定轮询的工作时间有多长.我只是用Google搜索并找到了上面的示例代码并实现了它,从表面上看,它很棒.我只是担心它会让事情变得糟糕down(在服务器上)和我将旧结果与new进行比较的方式会降低(在客户端上).

我们非常感谢您提供的任何和所有信息.

TIA.

Ali*_*tad 13

好的,我的两分钱:

  1. 正如其他人所说,SignalR是经过试验和测试的代码,所以我真的会考虑使用它而不是编写自己的代码.
  2. SignalR确实更改了一些IIS设置以优化IIS以进行此类工作.因此,如果您希望实现自己的,请查看在SignalR中完成的IIS设置更改
  3. 我想你正在做长轮询,以便你的服务器可以实现某种形式的服务器推送.请记住,这会将您的无状态HTTP计算机转变为有状态的计算机,如果您想扩展,则该计算机并不好.在负载平衡器后面长时间轮询并不好 :) 对我来说这是关于服务器推送的最糟糕的事情.
  4. ASP.NET使用ThreadPool来提供请求.长轮询将占用ThreadPool线程.如果你有太多这些线程,你可能最终陷入线程饥饿(和眼泪).作为一个大概的数字,100不是太多但是+1000.
  5. 甚至SignalR团队也表示,针对SingalR优化的IIS盒可能没有针对普通ASP.NET进行优化,他们建议将这些盒子分开.所以这意味着成本和开销.

在一天结束时,如果您正在解决业务问题(并不是因为它很酷),我建议使用长轮询,因为这将支付其成本,开销和头痛.


Mar*_*nes 10

我同意SLaks - 即如果你需要使用WebApi http://www.asp.net/signalr的实时网络,请使用SignalR .长轮询难以很好地实现,让其他人处理这种复杂性,即使用SignalR(WebApi的自然选择)或Comet.

在使用长轮询,Web套接字,服务器发送事件和永久帧(此处)之前,SignalR尝试其他3种形式的通信.

在某些情况下,您可能更适合使用简单的轮询,即每秒钟左右更新一次......请看一下这篇文章.但这是一个引用:

当您具有较高的消息量时,长轮询与传统轮询相比不会提供任何实质性的性能改进.事实上,情况可能会更糟,因为长期民意调查可能会失控,成为一个无节制的,持续不断的民意调查循环.

担心的是,如果网页上有任何重大负载,您的30秒ajax查询最终可能会成为您自己的拒绝服务攻击.

如果负载过多,即使是Bayeux(CometD)也会采用简单的轮询:

通过使用重新连接和间隔建议字段来限制客户端来解决增加的服务器负载和资源不足问题,这在最坏的情况下会退化为传统的轮询行为.

至于你问的第二部分.

如果您使用长轮询,那么理想情况下您的服务器应该只返回更新,如果实际上已经发生了某些变化,那么您的UI应该"信任"响应并假设响应意味着新数据.任何服务器推送类型方法都是如此.

如果您确实向下移向简单的轮询pullmethod,那么您可以使用内置的http方法来检测更新,使用If-Modified-Since标头,这将允许您返回304 Not Modified,因此服务器将检查时间戳object,如果自上次请求后已经修改了对象,则仅返回200.