【问题标题】:Node.js with Socket.io working locally but not remotely (request IP changed remote)带有 Socket.io 的 Node.js 在本地工作但不在远程工作(请求 IP 远程更改)
【发布时间】:2020-12-15 13:07:27
【问题描述】:

我觉得我已经用尽了我能找到的所有相关帖子和解决方案,但没有解决方案,也没有一个与我所看到的确切问题相符(尽管许多非常相似)。

简而言之,我有一个非常简单的 NodeJS socket.io 发射器和客户端示例。 当客户端网页与 nodeJS socket.io 发射器应用程序托管在同一主机上时,它会按预期运行。从任何其他主机执行的相同客户端网页会出现相同的问题。

基本上我收到如下连续消息;

404 [XHR]       http://192.168.0.41/socket.io/?EIO=3&transport=polling&t=NGc5_Pg    

我将在下面解释详细信息,但我认为确凿的证据是该请求的 IP 地址/主机已更改为托管客户端网页。

在同一主机(192.168.0.35)上运行时,我得到以下成功;

200 [XHR]       http://192.168.0.35:3000/socket.io/?EIO=3&transport=polling&t=NGc1BqD
101 [WebSocket] ws://192.168.0.35:3000/socket.io/?EIO=3&transport=websocket&sid=jIxHFTv6eoIXXGiRAAAH    
200 [XHR]       http://192.168.0.35:3000/socket.io/?EIO=3&transport=polling&t=NGc1Bqi&sid=jIxHFTv6eoIXXGiRAAAH

远程运行时,IP地址现在是网页服务器主机! (我确信有一些简单的原因导致我不明白) 为什么现在的请求 IP 是 .41 而不是 .35 ???

这是两个测试的更完整的比较;

工作中:客户端页面与节点发射器在同一主机上提供服务

200 [XHR]       http://192.168.0.35:3000/socket.io/socket.io.js                                                     Content-Type: application/javascript
200 [XHR]       http://192.168.0.35:3000/socket.io/?EIO=3&transport=polling&t=NGc1BqD                               Content-Type: text/plain; charset=UTF-8
101 [WebSocket] ws://192.168.0.35:3000/socket.io/?EIO=3&transport=websocket&sid=jIxHFTv6eoIXXGiRAAAH                Content-Type: text/plain; charset=UTF-8
200 [XHR]       http://192.168.0.35:3000/socket.io/?EIO=3&transport=polling&t=NGc1Bqi&sid=jIxHFTv6eoIXXGiRAAAH      Content-Type: text/plain; charset=UTF-8

失败:客户端页面服务于任何其他主机

200 [script]    http://192.168.0.35:3000/socket.io/socket.io.js                                                     Content-Type: application/javascript
404 [XHR]       http://192.168.0.41/socket.io/?EIO=3&transport=polling&t=NGc5_Pg                                
404 [XHR]       http://192.168.0.41/socket.io/?EIO=3&transport=polling&t=NGc61sS
404 [XHR]       http://192.168.0.41/socket.io/?EIO=3&transport=polling&t=NGc5_l5
...
...
... infinity        

请注意,端口 3000 已打开,并且正在成功地为 socket.io.js 提供服务。 此外,托管客户端网页(nginx、节点等)似乎并不重要

当远程运行时,我没有看到任何 CORS 或 XSS 错误——我认为这是有道理的——因为请求被更改为本地 IP/域?

如果能帮助我了解我在哪里无法理解或缺少什么,我将不胜感激!

这里是代码;

节点 testsockets.js

app.use(function(req, res, next) {
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
    res.setHeader("Access-Control-Allow-Headers", "Content-Type");
    res.setHeader("Access-Control-Allow-Methods", "PUT, GET, POST, PATCH, DELETE, OPTIONS");  
    res.setHeader('Access-Control-Allow-Credentials', false);  
    res.setHeader("Content-Security-Policy", "script-src 'self'");
    next();
  });

var options = {
  allowUpgrades: true,
  transports: ['websocket', 'file', 'htmlfile', 'xhr-polling', 'jsonp-polling', 'polling'],
  pingTimeout: 9000,
  pingInterval: 3000,
  httpCompression: true,
  origins: '*:*' 
};

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

app.use(bodyParser.json());
app.use(express.static('public'));

sub_client.subscribe('datahub.tsv.environment');

sub_client.on("message", function(channel, message){
   io.emit('event message', message);
   console.log("redis subscription message: " + JSON.stringify(message));
});

http.listen(3000, '192.168.0.35', () => {
  console.log('dataHUB NodeJS Redis Subscriber listening on *:3000');
});

客户端 HTML 页面

<!doctype html>
<html>
  <head>
    <title>Test Socket.IO Event Messages</title>
   <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
   <script src="http://192.168.0.35:3000/socket.io/socket.io.js" type="text/javascript"></script>
  </head>

<script>
  'use strict';

    let socket = io();
    socket.connect('http://192.168.0.35:3000');

    socket.on('event message', function(msg){
       $("p").html( msg);
    });
</script>

  <body>
    <div id="display" style="width:100%;">
      <p></p>
    </div>
  </body>
</html>

【问题讨论】:

    标签: node.js socket.io localhost http-status-code-404


    【解决方案1】:

    客户端代码似乎有问题。它无法连接到您传递的 URL。 试试 let socket = io('http://192.168.0.35:3000');或其他方式,如 io.connect(URL) 。

    默认情况下,如果未提供 URL,客户端中的 socket.io 会尝试连接到为其提供服务的服务器/主机。它无法获取 .35 IP URL ,因此它正在尝试连接到 .41,因为它是在那里托管和服务的。

    幸运的是,当服务器和客户端都在一起时,它可以正常工作,因为客户端默认尝试连接到为客户端提供服务的服务器,即 0.35 IP。它甚至没有使用您传递的正确 URL,但默认匹配套接字服务器!

    【讨论】:

    • 嗨 - 我不确定我是否理解这与我使用的代码有何不同?我实际上正在使用 i.connect(URL)。也许我没有正确理解您的建议。
    • 根据您提供的代码,您使用的是 socket = io() ,然后是 socket.connect(URL) 。您应该使用 socket = io(URL) 或 socket = io.connect(URL) 。
    猜你喜欢
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 2021-07-14
    • 2015-09-12
    相关资源
    最近更新 更多