Lightstreamer 背后的魔力是啥?

Posted

技术标签:

【中文标题】Lightstreamer 背后的魔力是啥?【英文标题】:What is the magic behind Lightstreamer?Lightstreamer 背后的魔力是什么? 【发布时间】:2012-05-15 03:20:29 【问题描述】:

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

但是,当您开始工作时,问题就会显现出来:

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

但是,当我查看Lightstreamer demo page 时,我看到它会一点一点地向客户端发送一个 JavaScript 文件,并且在每一步中,它都会发送一个对函数的调用,然后该函数就会被执行(我可以' t 做这部分)。似乎 Lightstreamer 使用 AJAX,因为请求只是显示在 Firebug 的控制台选项卡中,但它在 IE 中也像一个魅力。

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

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

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

有人可以帮忙吗?我认为应该有一个我不知道的小技巧或窍门将所有概念粘合在一起。有谁知道 lightstreamer 是如何解决这些问题的?

【问题讨论】:

【参考方案1】:

这里是 SockJS 作者。

如何让它跨浏览器?

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

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

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

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

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

有人可以帮忙吗?我认为应该有一个我不知道的小技巧或窍门将所有概念粘合在一起。有谁知道 lightstreamer 是如何解决这些问题的?

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

【讨论】:

Marek,问题是“lightstreamer 的魔力是什么”——你是说 SockJS 之类的魔力是什么? (例如,我们不需要 lightstreamer,因为 SockJS 处理跨平台 JS 客户端)?那 lightstreamer 服务器呢,它有什么魔力吗? 我问这个问题是因为:***.com/questions/19667644/…【参考方案2】:

您想要的方法是streaming。

如何让它跨浏览器?

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

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

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

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

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

除了以上问题,还有一些问题你需要考虑。

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

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

祝你好运。

【讨论】:

【参考方案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>

【讨论】:

是的,我试过了,但只有将 MIME 类型设置为 text/html 才有效。换句话说,您应该请求另一个 HTML 文档。如果您将响应设置为 application/javascriptapplication/x-javascripttext/javascript 它将不起作用。也解决不了我的问题。我可以使用 XMLHttpRequest 请求包含 JavaScript sn-ps 的 HTML 文件。但是,它在 IE 中不起作用。我可能会使用iframe,但它会显示加载程序。 Lightstreamer 可以在任何地方工作,并且不显示加载程序标志。 另外请注意,如果我使用XMLHttpRequest 获取包含&lt;script&gt;alert('loaded');&lt;/script&gt; JavaScript sn-ps 的不断加载的HTML 文件,它们将不会被执行。我的意思是,浏览器会在 JavaScript 标记到达时执行 JavaScript 代码,但仅限于普通请求,而不是 ajax 请求。【参考方案4】:

在您的情况下,最好的选择是在服务器端使用 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/(真的很酷,但没试过)

【讨论】:

我不想每次更新都建立一个连接(请求)。我只需要打开一个连接,并通过该单个连接更新客户端的浏览器。请参阅我的问题中的链接并在 Firebug 中检查它。

以上是关于Lightstreamer 背后的魔力是啥?的主要内容,如果未能解决你的问题,请参考以下文章

将事件处理程序添加到 LightStreamer

Loadrunner 和 Lightstreamer

如何模拟 LightStreamer?

Lightstreamer 新手:我应该如何解释这个 Web 请求?

获取 lightstreamer 发送的数据

Lightstreamer java se 客户端 maven