Socket.io + NodeJS 不适用于 Heroku

Posted

技术标签:

【中文标题】Socket.io + NodeJS 不适用于 Heroku【英文标题】:Socket.io + NodeJS doesn't work on Heroku 【发布时间】:2014-09-20 17:34:16 【问题描述】:

我正在做一个 API,它在 Heroku 上。但是我只在heroku方面遇到了socket.io的一些问题,当我在本地测试它时一切正常。 API 完全独立于前端,因此它们位于不同的域(和不同的主机)中。问题是在生产中,我没有成功连接套接字......

我有一些问题,都是关于 heroku 上的 socket.io 配置的。我知道有一些帖子提供了一些相关信息,但我发现的帖子是旧版本的 sockets.io 或旧版本的 heroku(heroku 似乎在过去 7 月改变了 websockets 的东西):

我不知道在heroku 上运行socket.io 之前是否需要激活一些东西。我阅读了一些关于此的帖子,但似乎都过时了...我尝试使用以下方式激活 Websockets:$ heroku labs:enable websockets,但我得到的回复是:! No such feature: websockets

我必须指定一个端口,还是 Heroku 有一个自动端口?

我需要两个连接吗?一个监听 POST/GET/PUT/DELETE,另一个监听套接字?

app.js

    var express = require('express');
    var app = module.exports = express();
    var port = process.env.PORT || 5000;
    var port_s = 3000;
    var server = require('http').createServer(express);
    ...
    app.listen(port);
    server.listen(port_s);

    require('./config/socket-io')(app, server, secret);
    app.post('/user', routes.users.register);
    ...

socket-io.js

module.exports = function(app, server, secret) 
    var clients = ;
    console.log("initiating sockets...");
    var sio = require('socket.io').listen(server);

    sio.sockets.on('connection', function (socket) 
        clients[socket.id] = socket;
        console.log("...new connection: "+socket.client.id);
        socket.emit('identification',  data : socket.client.id );

        socket.on('newShoutOut', function(data) 
            var receptor    = data.idTo;
            var emiter      = socket.client.id;
            //console.log("...new shout out from " +emiter+ " to "+receptor);
            var elem = findElement(sio.sockets['sockets'], 'id', receptor);
            sio.sockets.sockets[elem].emit('privateShoutout', data : data.data, from : emiter );
        );

        socket.on('disconnect', function() 
            //console.log("..."+socket.client.id + " disconnected");
        );
    );
;

function findElement(arr, propName, propValue) 
    for (var i=0; i < arr.length; i++) 
        if (arr[i].id === propValue)
            return i;
    ;

我再说一遍,一切都在本地主机上运行。我尝试了 localhost:5000 上的 API 和 localhost:80 上的客户端应用程序,所有套接字都工作正常。

谢谢。

【问题讨论】:

你能不能去命令行输入heroku logs然后告诉我你看到了什么? 【参考方案1】:

所以这里有几件事。如果您想使用 Heroku 的 Websocket 服务(实际上非​​常棒),您将需要重新编写代码以使用 websockets 的 einaros/ws 实现——然后通过 heroku 命令行添加该服务。 https://github.com/einaros/ws/blob/master/doc/ws.md

然而,由于您已经将应用程序编码为 socket.io,我将简单地修改您实例化 socket.io 库的方式:

var express = require('express'),
    app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server),

server.listen(process.env.PORT || 3000);

这应该可以解决您的问题,但请告诉我日志显示的内容。我认为挂断是您的应用程序和您的套接字在两个不同的端口上运行。

创建服务器后,您可以通过以下方式监听套接字事件:

io.sockets.on('connection', function(socket)  //'connection' or any other event

希望这会有所帮助。

【讨论】:

男人... 2/2。惊人的。你是对的,我从前端(3000)指定一个端口,在heroku上我想这是自动分配一个端口。之后我只剩下一个问题:如果我一方面有套接字,另一方面有 GET/POST/PUT 调用......我需要两个端口监听吗?还是一听就OK? 不,您不需要指定其他端口。 GET/POST 不会干扰您的套接字事件侦听器。 只是出于好奇,如果您从命令行运行heroku logs,在您之前的实现中,错误是什么? 抱歉。没有错误。我指定了一个端口,Heroku 忽略了require('socket.io').listen(server); 之后的所有代码。 @bencripps 你好!你认为你也可以为我的帖子提供建议吗(同样的问题,提供的解决方案不起作用)***.com/questions/62885098/…

以上是关于Socket.io + NodeJS 不适用于 Heroku的主要内容,如果未能解决你的问题,请参考以下文章

Socket.io 不适用于 https(让我们加密)

socket.io 不适用于传输:['xhr-polling']

CORS 不适用于 hapijs 和 socket.io

socket.io 广播不适用于 React

socket.io 连接不适用于 react.js

node.js 中的 socket.io 不适用于 3G 移动网络