服务器发送的事件和浏览器限制 [英] Server sent events and browser limits

查看:109
本文介绍了服务器发送的事件和浏览器限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Web应用程序,用于监听服务器发送事件.当我在打开多个窗口的状态下进行测试时,事情一直没有进行,我朝错误的方向猛击了好几次:最终,我意识到问题出在并发连接上.

I have a web application that listens for Server Sent Events. While I was working and testing with multiple windows open, things were not working and I banged my head for several times looking in the wrong direction: eventually, I realized that the problem was concurrent connections.

但是我测试的数量非常有限,即使我在Apache上运行测试(我知道我也应该使用node).

However I was testing a very limited number and even if I am running the test on Apache (I know, I should use node).

然后,我切换了浏览器,并发现了一些非常有趣的东西:显然,Chrome将服务器发送事件的连接限制为4-5,而Opera没有.另一方面,Firefox在同时进行4-5次连接后,拒绝加载任何其他页面.

I then, switched browser and noticed something really interesting: apparently Chrome limits Server Sent Events connections to 4-5, while Opera doesn't. Firefox, on the other hand, after 4-5 simultaneous connections, refuses to load any other page.

这背后的原因是什么?该限制是否仅适用于来自相同来源的SSE连接,或者如果我要测试来自其他域的开放连接,该限制是否会相同?我是否有可能滥用SSE并实际上阻止了浏览器,或者这是已知的行为?有什么办法解决吗?

What is the reason behind this? Does the limit only apply to SSE connections from the same source, or would it be the same if I were to test open them from a different domain? Is there any chance that I am misusing SSE and this is actually blocking the browsers, or this is a known behaviour? Is there any way around it?

推荐答案

在所有浏览器中的工作方式是,每个域都获得有限数量的连接,并且限制对于整个应用程序是全局的.这意味着,如果您打开一个用于实时通信的连接,则用于加载图像,css和其他页面的连接将减少一个.最重要的是,您不会为新的标签页或窗口获得新的连接,它们都需要共享相同数量的连接.这非常令人沮丧,但是有充分的理由限制连接.几年前,该限制在所有浏览器中均为2(基于( http://www.ietf.org中的规则/rfc/rfc2616.txt )HTTP1.1规范),但现在大多数浏览器通常使用4-10个连接.另一方面,移动浏览器仍然需要限制连接数量以节省电池.

The way this works in all browsers are that each domain gets a limited amount of connections and the limits are global for your whole application. That means if you have one connection open for realtime communication you have one less for loading images, css and other pages. On top of that you don't get new connections for new tabs or windows, all of them needs to share the same amount of connections. This is very frustrating but there are good reasons for limiting the connections. A few years back, this limit was 2 in all browsers (based on the rules in (http://www.ietf.org/rfc/rfc2616.txt) HTTP1.1 spec) but now most browsers use 4-10 connections in general. Mobile browsers on the other hand still needs to limit the amount of connections for battery saving purposes.

这些技巧可用:

  1. 使用更多主机名.通过分配ex. www1.domain.com,www2.domain.com,您将获得每个主机名的新连接.此技巧适用于所有浏览器.不要忘记将Cookie域更改为包括整个域(domain.com,而不是www.domain.com)
  2. 使用Web套接字. Web套接字不受这些限制的限制,更重要的是,它们不会与您网站的其余内容竞争.
  3. 打开新的选项卡/窗口时,请重新使用相同的连接.如果您已将所有实时通信逻辑收集到对象调用集线器中,则可以在所有打开的窗口上调用该对象,如下所示:

  1. Use more host names. By assigning ex. www1.domain.com, www2.domain.com you get new connections for each host name. This trick works in all browsers. Don't forget to change the cookie domain to include the whole domain (domain.com, not www.domain.com)
  2. Use web sockets. Web sockets are not limited by these restrictions and more importantly they are not competing with the rest of your websites content.
  3. Reuse the same connection when you open new tabs/windows. If you have gathered all realtime communication logic to an object call Hub you can recall that object on all opened windows like this:

window.hub = window.opener ? window.opener.hub || new Hub()

window.hub = window.opener ? window.opener.hub || new Hub()

在使用多线程和阻塞语言(例如Java或C#)时,要记住的另一件事是,冒着在长轮询请求中使用其余应用程序所需资源的风险.例如,在C#中,每个请求都锁定Session对象,这意味着在SSE请求处于活动状态时,整个应用程序将无响应.

Another thing to remember when using a multithreaded and blocking language such as Java or C# you risk using resources in your long polling request that are needed for the rest of your application. For example in C# each request locks the Session object which means that the whole application is unresponsive during the time a SSE request is active.

NodeJs对于这些事情非常有用,原因很多,因为您已经弄清楚了,如果您使用的是NodeJS,则可以使用socket.io或engine.io来解决所有这些问题,方法是使用websockets,flashsockets和XHR轮询,还因为它是非阻塞和单线程的,这意味着它在等待事物发送时将在服务器上消耗很少的资源.一个C#应用程序每个等待请求消耗一个线程,仅该线程就占用至少2MB的内存.

NodeJs is great for these things for many reasons as you have already figured out and if you were using NodeJS you would have used socket.io or engine.io that takes care of all these problems for you by using websockets, flashsockets and XHR-polling and also because it is non blocking and single threaded which means it will consume very little resources on the server when it is waiting for things to send. A C# application consumes one thread per waiting request which takes at least 2MB of memory just for the thread.

这篇关于服务器发送的事件和浏览器限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆