7

我要开发一个彗星编程框架,但我不能使用 Web Sockets 或服务器发送事件(因为浏览器支持真的很烂)。因此,我需要保持 HTTP 连接处于活动状态,并将分块数据发送回客户端。

然而,当你开始工作时,问题就会显现出来:

  1. 使用 XMLHttpRequest 是不可能的,因为 IE 在 3 时没有给xhr.responseTextxhr.readyState
  2. 隐藏iframe不会有用,因为当我将数据发送回客户端时,浏览器会显示加载器。
  3. 我尝试将 JavaScript 文件发送回客户端,每次都发送函数执行命令,但浏览器在完全加载之前不会执行 JavaScript。

但是,当我查看Lightstreamer 演示页面时,我看到它一点一点地将一个 JavaScript 文件发送回客户端,并且在每一步中,它都会发送一个对函数的调用,并且该函数只是被执行(我不能这样做部分)。似乎 Lightstreamer 使用 AJAX,因为请求只是显示在 Firebug 的控制台选项卡中,但它在 IE 中也像一个魅力。

我尝试使用他们在请求中设置的每个 HTTP 标头字段,但没有结果。我也尝试使用 HTTP Post 而不是 HTTP Get,但仍然没有结果。

我已经阅读了将近 20 篇关于如何实现彗星的文章,但似乎没有一篇文章能解决我遇到的问题:

  1. 如何让它跨浏览器?
  2. 当新数据从服务器到达时如何得到通知(我应该挂钩什么事件)?
  3. 如何使我的页面显示为完全加载给用户(如何实现它,以便浏览器不显示加载活动)?

有人可以帮忙吗?我认为应该有一个我不知道的小技巧或窍门将所有概念粘合在一起。有谁知道 lightstreamer 做了什么来克服这些问题?

4

4 回答 4

5

SockJS 作者在这里。

  • 如何让它跨浏览器?

这很难,预计要花几个月的时间在 Opera 和 IE 上获得流传输。

  • 当新数据从服务器到达时如何得到通知(我应该挂钩什么事件)?

有多种技术,取决于特定的浏览器。了解 Socket.IO 和 SockJS 支持的不同回退协议的介绍。

  • 如何使我的页面显示为完全加载给用户(如何实现它,以便浏览器不显示加载活动)?

同样,还有一些特定于浏览器的技巧。一种是在 onload 事件之后延迟加载 AJAX。其他是从 DOM 绑定和取消绑定 iframe。等等。如果您仍然感兴趣,请阅读 SockJS 或 Socket.io 代码。

有人可以帮忙吗?我认为应该有一个我不知道的小技巧或窍门将所有概念粘合在一起。有谁知道 lightstreamer 做了什么来克服这些问题?

基本上,除非你有非常充分的理由,否则不要重新发明轮子。使用 SockJS、Socket.io、faye 或任何其他已经解决了这个问题的项目。

于 2012-05-08T12:17:56.393 回答
4

您想要的方法是流式传输

如何让它跨浏览器?

考虑到大多数浏览器,没有一致的方法。您必须根据浏览器选择合适的传输方式。更糟糕的是,您必须依靠浏览器嗅探来识别正在使用的浏览器,而功能检测对此毫无意义。您可以将 XDomainRequest 用于 IE8+,XMLHttpRequest 用于非 IE,Iframe 用于 IE 6+。尽可能避免 iframe 传输。

当新数据从服务器到达时如何得到通知(我应该挂钩什么事件)?

这取决于所使用的传输方式。例如,XDomainRequest 触发进度事件,XMLHttpRequest 在块到达时触发 readystatechange 事件,Opera 和 IE 除外。

如何使我的页面显示为完全加载给用户(如何实现它,以便浏览器不显示加载活动)?

我不知道 iframe 的这个问题,但仍然出现在基于 WebKit 的浏览器中,例如带有 XMLHttpRequest 的 Chrome 和 Safari。避免这种情况的唯一方法是在 window 的 onload 事件之后进行连接,但是对于 Safari,这不起作用。

除了上述问题之外,您还必须考虑一些问题。

  1. 事件驱动服务器 - 服务器应该能够异步处理。
  2. 传输要求 - 服务器对所需传输的行为不同。
  3. 流格式 - 如果服务器要在单个块中发送大消息或多条消息,则单个块并不意味着单个数据。它可以是单个数据的片段或多个数据的串联。要识别什么是数据,应对响应进行格式化。
  4. 错误处理 - Iframe 传输不提供任何断开连接的证据。
  5. ...

最后但并非最不重要的一点是,与长轮询相比,实现流式传输非常令人厌烦。我建议您使用可靠的框架来执行此操作,例如我创建和管理的socketiosockjsjquery socket 。

祝你好运。

于 2012-05-07T11:51:15.400 回答
3

但是浏览器在完全加载之前不会执行 JavaScript。

您是否尝试过发回包含在标签中的<script>代码?例如,而不是:

<script type="text/javascript">
f(...data1...);
f(...data2...);

尝试

<script type="text/javascript">f(...data1...);</script>
<script type="text/javascript">f(...data2...);</script>
于 2012-05-06T04:44:53.763 回答
1

在您的情况下,最好的选择是在服务器端使用 JSONP + Long Pulling。您只需要记住在连接断开(超时)或收到响应时重新连接。

jquery中的示例代码:

function myJSONP(){
    $.getScript(url, {
        success: function(){
            myJSONP(); //re-connect
        }, 
        failure: function(){
            myJSONP(); //re-connect
        }
    })
} 

显然,您来自服务器的响应必须是调用您的全局函数的 javascript 代码。

或者,您可以使用一些 jquery JSONP 插件。

或者看看这个项目http://www.meteor.com/(真的很酷,但没试过)

于 2012-05-06T04:54:58.030 回答