移动网络中 8080 或 80 端口上的 WebSocket 连接失败

Posted

技术标签:

【中文标题】移动网络中 8080 或 80 端口上的 WebSocket 连接失败【英文标题】:WebSocket connection failed in mobile network on port 8080 or 80 【发布时间】:2013-12-12 00:35:47 【问题描述】:

在我的 Web 应用程序中,我使用 Node.js 和 Socket.io。

当我在本地或我的 wifi 网络中测试应用程序时,一切都很好,但由于我切换到移动数据,我收到连接错误:

WebSocket 连接到 'ws://url/socket.io/1/websocket/' 失败:WebSocket 握手期间出错:意外的响应代码: 502

似乎我的移动提供商阻止了端口 8080 和 80,但使用 nodejitsu 切换到另一个端口似乎是不可能的。

有人对如何处理移动网络、node.js 和 socket.io 有一些经验吗?

编辑: 作为主持人,我尝试免费订阅 Heroku 和免费订阅 Nodejitsu。

在移动设备上,我使用移动设备和 wifi 检查了 http://websocketstest.com/ 上的端口。在移动设备上,端口 80 和 8080 的测试失败。 我想也许我可以将端口更改为 443,但即使我将 server.listen() 设置为端口 443,nodejitsu 似乎也会监听端口 80。

我认为 WebSockets 可能通过另一个端口实现,但我不知道如何更改端口或为什么 nodejitsu 只是监听端口 80。

【问题讨论】:

【参考方案1】:

HTTP 502 表示“错误网关”,通常是客户端和服务器之间路径上某处反向代理的标志。

如果您确定不是因为您自己的设置,您应该尝试禁用 socket.io 的 websocket(和 flashsocket)传输:

var io = require('socket.io').listen(...);

io.set('transports', [ 'xhr-polling', 'jsonp-polling', 'htmlfile' ]);

【讨论】:

我试过了,但似乎通过轮询我得到了很大的延迟。您能否更详细地解释一下“‘坏网关’通常是反向代理的标志”是什么意思。 @yves 你能解释一下(通过编辑你的问题)你的确切服务器设置是什么吗?你的 Node 应用程序是直接暴露给外界的,还是你也在使用 nginx 之类的东西?您的服务器在哪个端口上侦听?我同意使用轮询传输对延迟确实很不利,但如果问题在于您的移动提供商无法正确处理 WebSocket 连接,那么您真的无能为力。 @yves 我认为要么是您的移动提供商的错,要么您使用了某种形式的移动数据压缩服务(例如 Opera Turbo)。 如果我通过https 调用该页面,它似乎可以工作,因为它使用的是端口 443。 @yves 是的,听起来您的移动提供商正在代理纯 HTTP 流量,这会导致 WebSockets 出现问题【参考方案2】:

您的 node.js 应用程序使用 websockets 并在本地和 wifi 网络上工作。使用移动数据网络时,它会出现 502 失败。这是我要回答的问题,而不是 heroku/nodejitsu 编辑。

最可能的原因是网络中的错误跃点,例如反向代理。要通过反向代理使用 Websockets,您必须使用 http1.1 并在连接时升级以从 http 协议转到 ws 协议。一些代理(尚)不支持 http 升级,其他一些东西(例如 @roberklep Opera Turbo)会导致 websockets 无法工作。

从端口 80 上的 http 移动到端口 443 上的 https(使用 SSL,现在称为 TLS)会在传输层加密数据。大多数不良跃点都设置为直接发送数据,从而解决您的问题。

我发现另一个 *** Q&A 显示了一些在 node.js 中设置 https 的代码 该帖子的关键部分是:

var sslOptions = 
  key: fs.readFileSync(__dirname + '/../ssl/server.key,
  cert: fs.readFileSync(__dirname + '/../ssl/server.pem,
  ciphers: 'ECDHE-RSA-AES256-SHA:AES256-SHA:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM',
  honorCipherOrder: true ;

var server = https.createServer(sslOptions, app); server.listen(443);

我还发现了一个有用的introduction to SSL/TLS,其中包含有关如何获得免费证书的说明。

【讨论】:

【参考方案3】:

您必须设置数据传输配置:

var io= require('socket.io');
io.set("transports", ["xhr-polling"]);

【讨论】:

谢谢,感谢您的帖子,我解决了这个deployd 错误!!

以上是关于移动网络中 8080 或 80 端口上的 WebSocket 连接失败的主要内容,如果未能解决你的问题,请参考以下文章

在端口 80 上为 Tomcat 和在 8080 上的 Apache 使用相同的 SSL 证书

8080 端口上的 Gitlab

关于端口的问题!

将端口从 8080 更改为 80,以查看域名上的 JBoss/Wildfly Java 应用程序,而不是 IP 地址

如何将默认 80 端口更改为我的域名的 tomcat 8080

如何将Tomcat的端口从8080改为80?