在 Heroku 上部署我的应用会破坏 websockets 协议(protocol)。
它适用于本地主机,不适用于 Heroku。在浏览器中,我得到:
WebSocket connection to 'wss://node-omi.herokuapp.com/socket.io/?EIO=2&transport=websocket&sid=*' failed: Error during WebSocket handshake: Unexpected response code: 503
在服务器端,我获取日志:
2014-08-12T15:05:24.761611+00:00 heroku[router]: at=error code=H13 desc="Connection closed without response" method=GET path="/socket.io/?EIO=2&transport=websocket&sid=****" host=node-omi.herokuapp.com request_id=* fwd="*" dyno=web.1 connect=3ms service=3ms status=503 bytes=864
这是我的服务器脚本的一部分:
var express = require('express'),
http = require('http'),
socket_io = require('socket.io');
var app = express(),
server = http.Server(app),
io = new socket_io(server).of('/test');
io.on('connection', this.connection.bind(this));
app.get('/client.html', function(req, res, next) { ... });
app.use('/', express.static(__dirname + '/public', {'index': ['index.html']}));
server.listen(process.env.PORT || 5000);
我的代码有什么问题?有人成功地使用 Express 4.8.3 和 Socket.io 1.0.6 构建了 socket.io 服务器吗?套接字适用于轮询,但我真的需要 websockets 才能工作。感谢您的回复。
最佳答案
Heroku 上的 Websocket 支持已经从测试版转为官方支持,因此在撰写本文时,修复可能只是简单地 labs:enable websockets
但您应该不再需要这样做, 你开箱即用的 websockets。
警告!
但作为对阅读此问题的其他人的警告,在 Heroku 上使用 socket.io 可能会出现问题,因为围绕 sticky sessions 存在分歧。
Heroku 明确表示 against them但是(缺少下面描述的相当糟糕的解决方法)socket.io 需要它们:
https://github.com/Automattic/engine.io/issues/261
^tl;dr 如果这个很长的线程是在 v1.0 之前,socket.io 使用 Heroku 等非粘性服务,您只需要使用 redis 适配器来管理您的 dynos 之间的共享状态。这在 1.0 中被删除,由于代码维护成本,socket.io 团队担心将其放回原处。要求取回它的 github 问题已经关闭,消息是一旦有人非常想要它来进行 PR,他们将很乐意调查它。
解决方法!
有一个变通方法是将 socket.io 限制为仅使用 websocket 传输,这不需要粘性 session 。例如:
服务器:
io.set('transports', ['websocket']);
客户端
var socket = io.connect(host, {
transports: ['websocket']
});
但是,这消除了 socket.io 1.0 使用 engine.io 带来的很多好处。
还有其他 websocket 框架,如 Faye在 Heroku 上工作得很好。
关于Heroku 上的 Node.js Socket.io 抛出 H13,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25268160/