【问题标题】:Chrome & Safari revert to xhr-polling rather than websockets with socket.ioChrome 和 Safari 使用 socket.io 恢复为 xhr-polling 而不是 websockets
【发布时间】:2011-09-10 23:07:19
【问题描述】:

我对 websockets 和 socket.io 有疑问。当我尝试使用 socket.io 连接到我的节点服务器时,它最初使用 websockets 进行连接,但不久之后又恢复为 jsonp-polling。

这是我连接时节点服务器的输出:

8 Jun 07:01:15 - Initializing client with transport "websocket"
8 Jun 07:01:19 - Initializing client with transport "jsonp-polling"
8 Jun 07:01:19 - Client 16630339180119336 connected

这发生在 Chrome 和 Safari 中。 我已经更新到最新的 socket.io 版本 0.6.17 并且正在运行节点 0.4.7。

我已尝试按照 github 和 SO 上的建议删除我的 cookie 和缓存,但问题仍然存在。此外,当我尝试强制使用 websockets 时,它永远不会与会话 ID 完全连接。

有人有什么想法吗?

【问题讨论】:

  • 既然升级到 jsonp 就意味着你以跨域的方式使用 socket.io。尝试在同一个域上运行您的 websocket 服务器
  • 我在不同的 IP 上运行它,因为我需要在端口 80 上运行节点,这会导致我的 Web 服务器与 Apache 发生冲突。 websockets/flashsockets不能跨域使用吗?
  • websockets 和 flashsockets 跨域工作,您可以在 socket.io src 中看到它们都在 xdomainCheck 函数中返回一个毯子 true
  • 可能与代理有关,如果涉及代理,则与客户端无关。 Apache 是否充当此 socket.io 服务器的代理?
  • 最后一条评论可能是原因。如果您的节点在 Apache 或 Nginx 之类的代理后面运行,则您无法运行 WebSocket(除非您专门为 TCP 代理打了补丁)。

标签: javascript node.js websocket socket.io


【解决方案1】:

目前所有浏览器默认不支持 Websocket API(据我所知)它应该在 chromium 上工作,尽管尝试在 chromium 或 firefox 上测试它(在编辑默认设置后),看看是否仍然恢复到XHR 轮询。

我在不同的 IP 上运行它,因为我需要在端口 80 上运行节点,这会导致我的 Web 服务器与 Apache 发生冲突。 websockets/flashsockets不能跨域使用吗?

现在可能有两个不同的原因导致这里的错误

  1. Web/Flash Sockets 不会让你连接到 node.js 客户端,除非你指定一个不同的端口,比如 81,或者你特别指定 apache 来代理传入的请求到 Node。 一个简单的解决方案可能是编写基于 Node.js 的 HTTP 服务器来仅中继来自 Apache 的数据(并将 Apache 设置为在 80 的不同端口上运行)

    This link 告诉如何做到这一点......在这个过程中,你可以让 Node.js 做一些事情,比如检查请求是否来自 websocket/httpbrowser 如果那是 http 浏览器,如果不是,则将请求转发给 Apache,即如果那是来自网络/闪存套接字然后相应地处理套接字。或如对该问题的评论。指定 APACHE 代理到 Node.js。

  2. Flashsockets 要求您在端口 843 上提供跨域策略文件,您确定要提供跨域文件吗? (我认为 socket.io 具有执行此操作的内置功能,但检查起来仍然很好。)

如 socket.io 主网站所述

为了在每个浏览器上提供实时连接,Socket.IO 在运行时选择最有能力的传输,而不影响 API。

  • WebSocket
  • Adobe® Flash® Socket
  • AJAX 长轮询
  • AJAX 多部分流式传输
  • 永远的 iframe
  • JSONP 轮询

很明显,如果 websocket 被禁用并且 Adob​​e Flash Socket 连接失败(这可能是由于策略文件不可用),它将恢复为 AJAX 长轮询。

这是一个跨域文件的示例代码,您可以将其包含在您的代码中,看看这是否会使您的服务器使用 websockets 运行。

var net = require("net");

// Node.js 

var Policy = net.createServer(function(socket)
{
    socket.setEncoding('utf8');
    socket.on('connect',function(){
        console.log("Policy Request");
        socket.end("<?xml version=\"1.0\"?><!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" secure=\"false\"/></cross-domain-policy>");
    });
});

Policy.listen(843); 

【讨论】:

    猜你喜欢
    • 2015-05-04
    • 2013-04-03
    • 2012-06-20
    • 2013-08-01
    • 2013-04-06
    • 2012-02-10
    • 2012-11-16
    • 2019-05-09
    • 2012-03-03
    相关资源
    最近更新 更多