【问题标题】:WebSocket suddenly refuses connectionWebSocket 突然拒绝连接
【发布时间】:2016-03-30 18:31:48
【问题描述】:

对于我的项目,我需要一个 VPS,所以我在 DigitalOcean 上购买了一个。我安装了 MongoDB、Laravel,整个东西都在 Nginx 上运行。

今天早些时候,我问了一个关于计时器的问题,建议是使用 WebSockets。根据评论,最好的方法是使用带有 Socket.io 的 NodeJS。所以我做到了。

我在这里(本地)遵循this 教程,并且在本地主机上完全没有问题。

所以我的下一步是将代码上传到我的网络服务器并将其与 Laravel 结合起来。我在建立连接时遇到了一些问题,但在我找到this Stackoverflow 帖子后,它终于奏效了。服务器正在发送一个日期对象,屏幕上的计时器正在实时更新。

但它仅在我通过node 终端命令手动启动脚本时才有效。因此,我遵循了 DigitalOcean 上的 this 教程,您使用 PM2 继续运行脚本,即使我关闭终端/注销我的 VPS 也是如此。一切正常,计时器仍在更新,实际上我很惊讶我没有遇到那么多问题..

..直到 5 分钟后。突然之间,WebSocket 停止工作。也许我在没有意识到的情况下打错了字,也许服务器注意到代码中有一些我没有注意到的变化。我不知道,但是当我查看开发人员控制台时,它说:

GET http://<my-domain-ip>:8080/socket.io/?EIO=3&transport=polling&t=LF8I2CO net::ERR_CONNECTION_REFUSED

当然,我在谷歌上搜索了很多,并根据(大部分)Stackoverflow 答案对我的代码进行了各种更改,但现在我真的缺乏想法,完全不知道为什么我的代码不起作用。

server.js 文件:

var http = require('http');
var url = require('url');
var fs = require('fs');
var io = require('socket.io');

var server = http.createServer(function (request, response) {
    var path = url.parse(request.url).pathname;

    switch(path) {
        case '/' :
            response.writeHead(200, { 'Content-Type' : 'text/html'});
            response.write('hello world');
            response.end();
            break;
        case '/socket.html' :
            fs.readFile(__dirname + path, function (error, data) {
                if(error) {
                    response.writeHead(404);
                    response.write("Oops, this doesn't exist - 404");
                    response.end();
                } else {
                    response.writeHead(200, {'Content-Type' : 'text/html'});
                    response.write(data, 'utf8');
                    response.end();
                }
            });
            break;
        default :
            response.writeHead(404);
            response.write("Oops, this doesn't exist - 404");
            response.end();
            break;
    }
});

server.listen(8080, '<private ip>');
console.log('Server running at http://<private ip>:8080/');


var listener = io.listen(server);

listener.sockets.on('connection', function (socket) {
    setInterval(function () {
        socket.emit('date', {'date' : new Date()});
    });

});

(我必须根据 DigitalOcean 教程设置私有 IP,以便 Nginx 使其工作)。

客户端的Javascript代码:

 <script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>

                    <script>
                        var baseURL               = getBaseURL(); // Call function to determine it
                        var socketIOPort          = 8080;
                        var socketIOLocation      = baseURL + socketIOPort; // Build Socket.IO location
                        var socket                = io(socketIOLocation);

                        //Build the user-specific path to the socket.io server, so it works both on 'localhost' and a 'real domain'
                        function getBaseURL()
                        {
                            baseURL = location.protocol + "//" + location.hostname + ":" + location.port;
                            return baseURL;
                        }

                        socket.on('date', function (data) {
                            $('#date').text(data.date.getHours() + ':' + data.date.getMinutes() + ':' + data.date.getSeconds());
                        })
                    </script>

如果我没记错的话,我还设置了一些选项,例如 proxy_passUpgrade $upgrade,但我不记得我在哪里读到了那个/我将它应用到了哪个文件,但据我所知,这些选项是设置正确。

有人知道问题出在哪里吗?因为我真的没有想法了。

提前致谢!

【问题讨论】:

  • 托管公司通常有办法“管理”长期运行的连接以保护他们的资源。一种可能性是您的托管基础​​设施需要专门为长时间运行的 webSocket 连接进行配置,因此 nginx(或其他一些网络设备)在一段时间后不会自动终止它。这不是所有托管都通用的东西 - 它特定于您在特定托管公司的特定 VPS 的配置,因此您必须从他们那里获得有关此主题的任何指导。
  • 可能的帮助:nolanlawson.com/2013/05/31/…
  • 我根据您提到的文章将端口更改为 443 并立即生效!我还联系了 DigitalOcean,他们说 WebSocket 应该继续工作,问题可能是我的 Nginx 服务器上的一些配置错误。但是 WebSockets 现在运行了几个小时没有任何问题,所以感谢您的帮助!

标签: javascript node.js nginx websocket socket.io


【解决方案1】:

托管公司通常有“管理”长期运行的方法 连接以保护他们的资源。一种可能性是您的 托管基础设施需要长期专门配置 运行 webSocket 连接,所以 nginx (或其他一些 网络设备)在一段时间后不会自动杀死它 的时间。这不是所有托管都通用的东西 - 它是 特定于您的特定 VPS 的配置 特定的托管公司,因此您必须获得任何指导 这个话题来自他们。

可能的帮助: http://nolanlawson.com/2013/05/31/web-sockets-with-socket-io-node-js-and-nginx-port-80-considered-harmful/

我变了:

server.listen(8080, <private ip>);

到:

server.listen(443);

还有:

var socketIOPort = 8080;

到:

var socketIOPort = 443;

感谢jfriend00

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-11
    • 2021-02-02
    • 2018-08-06
    • 2016-08-16
    • 1970-01-01
    • 2018-06-06
    • 2020-10-08
    • 2014-09-08
    相关资源
    最近更新 更多