Javascript socket.io—数百个请求,而不是一个连接

Javascript socket.io—数百个请求,而不是一个连接,javascript,node.js,sockets,Javascript,Node.js,Sockets,我创建了一个简单的应用程序,从socket.io开始,但当我运行它时,Chrome(在其他浏览器中测试,结果相同)会占用我所有的CPU并发出许多请求: 我对sockets还不熟悉,但我确信它不应该这样工作。在浏览器中运行的代码非常简单,它应该只连接到套接字并将所有接收到的数据记录到控制台: index.html <!DOCTYPE html> <html> <head> <script src="https://cdn.socket.io/so

我创建了一个简单的应用程序,从socket.io开始,但当我运行它时,Chrome(在其他浏览器中测试,结果相同)会占用我所有的CPU并发出许多请求:

我对sockets还不熟悉,但我确信它不应该这样工作。在浏览器中运行的代码非常简单,它应该只连接到套接字并将所有接收到的数据记录到控制台:

index.html

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.socket.io/socket.io-1.2.0.js" charset="UTF-8"></script>
</head>
<body>
<script type="application/javascript">
    var Sockets = io.connect('http://localhost:4000');
    Sockets.on('Test', function (data) {
        console.log(data);
    });
</script>

</body>
</html>
当我运行服务器
node server.js
时,我得到了
服务器在端口4000运行的消息,一切看起来都很好。但是,当我在浏览器中打开index.html时,节点控制台会被连接的用户发送垃圾邮件。浏览器不是连接一个客户端,而是每秒发出几十个请求。当我关闭浏览器时,有一段时间没有输出,然后节点控制台被
user disconnected
消息垃圾邮件发送

此服务器应将通过POST发送的所有数据重定向到连接的套接字。当我发出这个POST请求时,节点服务器会收到它(我知道,因为它会将它打印到节点控制台)。但是套接字客户端没有接收到它,因为浏览器控制台中没有输出(但浏览器仍然每秒建立几十个新连接)


这里出了什么问题?首先我觉得我搞砸了,所以我回去复制粘贴的代码(不是用英语,而是用捷克语),但没有更改。本教程有很多正面反馈,因此我的计算机可能有问题。但是什么?

您从socket.io服务器以外的其他web服务器运行该页面的配置将无法正常工作。需要进行三项更改之一才能使其正常工作:

  • 通过从与socket.io相同的服务器加载网页,您可以对网页和socket.io连接使用“同一来源”。这意味着您需要直接从socket.io web服务器加载网页

  • 您可以将socket.io web服务器配置为接受跨源连接(CORS连接)

  • 您可以将socket.io客户端配置为使用webSocket直接连接,而无需执行socket.io的常规预览和常规http请求

  • 如果您正在测试您打算真正部署的东西,那么您最好将现有的socket.ioweb服务器设置为您的网页,并直接从中加载网页



    造成这种情况的另一个可能原因是socket.io的客户端和服务器版本不兼容。您应该绝对确保客户端和服务器上的socket.io版本相同。如果从socket.io web服务器从
    /socket.io/socket.io.js
    获取客户端socket.io库,则客户端版本将我将自动始终匹配服务器版本。从CDN加载它的方式,您必须手动确保版本相同。

    因此,为了找到确切的错误,我从socket.io网站下载了示例socket chat。运行它时,我经历了完全相同的错误行为-浏览器正在打开许多socket con每秒钟连接一次,而不是保持连接一次


    因此,我删除了node_modules文件夹,并使用npm再次安装这些模块,哇,它成功了。很可能文件在下载过程中被破坏了,但这次再次执行相同的过程仍然有效。

    我也遇到了同样的问题,通过以下一个示例,客户端使用socket.io fr的源代码本cdn:

    每当我尝试运行该文件时,都会创建大量客户端(无论我是双击html文件,还是将其放在web服务器(如IIS)下)。然后我意识到它可能是较旧的版本,我只是使用了此来源发布的最新版本:

    现在一切都好了。
    希望这对您说“在我的浏览器中打开index.html”有所帮助,这到底意味着什么?您是直接从文件系统打开它吗?您应该通过web服务器打开它,而不是通过文件系统。由于socket.io的连接方式,如果web服务器上没有CORS配置,它将无法正常工作到跨源服务器。
    http://locahost:4000
    将是一个交叉原点endpoint如果您正在从文件系统打开index.html,并且不允许您正确连接。@jfriend00我正在使用“运行”按钮。正如您在屏幕截图中看到的,url是localhost:PhpStorm'sport/somepath/index.htmlRun按钮实际上是做什么的?我再次问。是从文件系统还是从web服务器加载
    index.html
    ?它需要从web服务器加载。仅供参考,您的web服务器代码没有显示任何我想要的方式t提供index.html,因此我怀疑您是从文件系统加载它,这可能是错误的,也是问题的原因。@jfriend00“运行”PhpStorm中的按钮启动PhpStorm中的内部Web服务器。我可以通过输入PhpStorm中配置端口的计算机IP从局域网中的其他计算机访问该页面,因此必须有一个Web服务器。我不这么认为。请求没有被阻止,节点服务器接受它们,在Chrome开发者工具的网络选项卡中,它们都列为200好的。出于某种原因,它们只是每秒被复制很多次。为了确保这一点,我启用了CORS,这没有什么区别。@AdamJežek-您的体系结构是错误的,并且没有模仿您在实际部署中使用的任何东西。修复该体系结构,我打赌您的问题会消失。FWIW,我认为这是错误的可能是socket.io的最新版本中引入了一个问题。在过去几周中,我看到了几份与您报告的行为类型相同的报告,三年来从未见过。但是,我敢打赌,如果使用适当的体系结构,您可以避免此问题。@AdamJežek-为什么坚持从一个不是您的实际web服务器加载web页面服务器?只需向web node.js服务器添加一个路由即可加载
    var app = require('express')();
    var http = require('http').Server(app);
    var bodyParser = require("body-parser");
    var io = require('socket.io')(http);
    var port = 4000;
    
    http.listen(port, function () {
        console.log('Server running at port ' + port);
    });
    
    var urlencodedParser = bodyParser.urlencoded({extended: false});
    app.post('/', urlencodedParser, function (req, res) {
        if (!req.body) return res.sendStatus(400);
        var post = req.body;
        io.emit("Test", post.data);
        console.log(post.data);
        res.send('true');
    });
    
    io.on('connection', function(socket){
        console.log('a user connected');
        socket.on('disconnect', function(){
            console.log('user disconnected');
        });
    });