Socket.io 适用于 localhost 但不适用于 Heroku 服务器

Posted

技术标签:

【中文标题】Socket.io 适用于 localhost 但不适用于 Heroku 服务器【英文标题】:Socket.io works with localhost but not on Heroku server 【发布时间】:2016-04-02 14:46:25 【问题描述】:

我目前正在尝试使用 socket.io 和 node.js 服务器与 Unity 脚本进行通信。我已经将所有东西都连接起来并使用 localhost,但由于某种原因,当我将它移植到我的 Heroku 服务器时,它无法连接。我假设它可能与URL有关?我是 socket.io 的新手,因此我们将不胜感激。

我的 node.js 服务器:

var express = require('express');
var app = express();
var expressWs = require('express-ws')(app);
var path = require('path');

var server = require('http').createServer(app);
var io = require('socket.io')(server);

io.on('connection', function(socket) 
    socket.on('beep', function()
        socket.emit("speed", data: 5);
        console.log('beep recieved');
    );

    socket.on('change-speed', function(data) 
        console.log('change speed recieved: ' + data);
        socket.emit("speed", newSpeed: data);
    );

    socket.on('ios-connection', function(data) 
        console.log('ios connection with message: ' + data);
    );

);

app.set('port', (process.env.PORT || 5000));

app.listen(app.get('port'), function() 
    console.log('Node app is running on port', app.get('port'));
);

我的连接网址:

ws://<heroku app name>.herokuapp.com:5000/socket.io/?EIO=4&transport=websocket

【问题讨论】:

嗨,Caroline,你解决了这个问题吗?我面临着一个类似的问题 【参考方案1】:

我已经部署了您的代码,并进行了细微的更改,并且它在 heroku 上运行良好,请查看它。 服务器端 app.js

var express = require('express');
var app = express();
app.set('port', (process.env.PORT || 5000));

var server = app.listen(app.get('port'), function() 
    console.log('Node app is running on port', app.get('port'));
);

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

app.use(express.static("./views"));

app.use(function(req, res, next) 
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
);

app.get('/', function (req, res) 
    var path = __dirname + '/views/index.html';
    console.log(path);
    res.sendFile(path);
);

io.on('connection', function(socket) 
    socket.on('beep', function()
        socket.emit("beep", data: 5);
        console.log('beep recieved');
    );

    socket.on('change-speed', function(data) 
        console.log('change speed recieved: ' + data);
        socket.emit("speed", newSpeed: data);
    );

    socket.on('ios-connection', function(data) 
        console.log('ios connection with message: ' + data);
    );
);

package.json


  "name": "socketio",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": 
    "test": "echo \"Error: no test specified\" && exit 1",
    "start" : "node app.js"
  ,
  "author": "inampaki",
  "license": "ISC",
  "dependencies": 
    "express": "^4.13.3",
    "express-ws": "^0.2.6",
    "socket.io": "^1.3.7"
  

index.html

<script src="/socket.io.js"></script>
<script>
  var socket = io.connect('/');
  socket.on('speed', function (data) 
    console.log('speed Message Received!');
    console.log(data);    
  );

  socket.on('beep', function (data) 
    console.log('beep Message Received!');    
    console.log(data);    
  );
  socket.emit("beep", beep : true);
  socket.emit("change-speed", "change-speed" : true);
  socket.emit("ios-connection", "ios-connection" : true);


</script>

注意将 index.html 和 socket.io.js 保存在 views 文件夹中。我部署它的 URL 是 socketip

【讨论】:

代码正在运行(就像我的旧代码一样),但我仍然无法从 Unity 与该 URL 建立连接。 你在 Unity Boo 或 C# 中使用哪种语言你能分享代码块吗?可能正在讨论那一方将解决问题。【参考方案2】:

问题几乎可以肯定是端口号不正确。

在您的应用程序中,您正在检查 process.env.PORT,如果它设置,则默认为 5000。

然而,在您的 ws URL 中,您似乎总是希望您的应用程序正在侦听端口 5000。

您可以通过在项目的根目录中运行以下命令来检查应用程序的配置设置:

heroku run printenv

这将打印一个配置变量列表,包括当前设置的PORT 值,例如:

PORT=9352

您应该在构建 ws URL 时使用此端口,例如:

ws://your-app.herokuapp.com:9352/socket.io/?EIO=4&transport=websocket

【讨论】:

我这样做了,每次我执行 printenv 时,它都会给我一个不同的端口。反正我试过了,还是不行 我应该将他的 ws://your-app.herokuapp.com:9352/socket.io/?EIO=4&transport=websocket 放在 procfile 中的哪个位置?【参考方案3】:

我找到了方法!! 团结一致

如果您在本地主机中运行服务器。网址应该有“:端口” 示例(端口 = 5000)

ws://127.0.0.1:5000/socket.io/?EIO=4&transport=websocket

但如果你已经部署到 **heroku url 必须删除“:port”

ws://<heroku app name>.herokuapp.com/socket.io/?EIO=4&transport=websocket

这对我有用!

【讨论】:

【参考方案4】:

好的,出于某种原因,我在这个问题线程上尝试了所有方法,并且成功了。然而,不是一个单一的答案有效,而是每个答案的组合。

首先,我删除了 URL 中的 :PORT 部分,有点像 Chinnawat Sirima 所说的那样。现在是……

ws://.herokuapp.com/socket.io/?EIO=4&transport=websocket

然后,出于某种原因,使用来自 dangalg 的 answer/teyou 的 repo 的代码启动服务器确实有效(我还注意到 teyou 的 url 也没有端口)。

var express = require('express');
var app = express();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
var PORT = process.env.PORT || 3000;

(more code here)

http.listen(PORT,function()
    console.log("Listening to port " + PORT);
);

为什么我说“出于某种原因”?因为我仍然不知道我做了什么哈哈。我的猜测是我以 Heroku 不喜欢的方式设置服务器,但每天 localhost 都会这样做。因为 localhost 不在乎。

我只是重新编译它,因为在过去的 8 个小时里,我或多或少地对这个问题感到沮丧。所以我希望这对其他人有帮助,不要浪费宝贵的时间和睡眠。

(顺便说一句,我的 Heroku 中没有 PORT 变量,我还有其他名称,我想这是另一个无用的行,但我不会再碰它,以防我再次破坏它:D)。

【讨论】:

【参考方案5】:

如果您已将应用程序部署到 Heroku,请从服务器的 URL 中删除给定的端口号,它应该可以正常工作。 ws://<heroku app name>.herokuapp.com/socket.io/?EIO=4&transport=websocket 当您在本地测试应用程序时,您可以访问socket via http://localhost:YOUR_PORT_NUMBER wheres,部署后不需要指定端口。

【讨论】:

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

node ios socket.io SSL 适用于 xcode 调试,但不适用于 ipa install

socket.io heroku 请求超时

Socket.io 无法连接,求助于“轮询”

Java socket.io 客户端

在真实的服务器中运行socket.io服务器,而不是localhost?

我可以从 Socket.io 访问 cookie 吗?