【问题标题】:Using Socket.IO from Node.js to connect to external server使用 Node.js 中的 Socket.IO 连接到外部服务器
【发布时间】:2018-01-28 09:36:38
【问题描述】:

背景:我有一个 node.js 服务器在我的本地主机上运行(称之为服务器 A);以及在https://example.net:3000 运行node.js 的外部服务器(称为服务器B)。我无法控制或访问服务器 B(它是我家中 IoT 设备的仪表板站点),但我需要使用 socket.io 连接并发出特定消息。

我可以从一个平面 javascript 文件(客户端)轻松连接到它,但需要它运行服务器端(最终目标是使它成为我可以通过 HTTP 请求调用的东西); How to connect two node.js servers with websockets? 等示例表明我应该能够使用 node.js 中的 socket.io-client 并使用几乎相同的代码来实现相同的结果。但是当我从 node.js 运行代码时,我无法连接到套接字。

以下是在平面 javascript 文件中成功运行的代码。我知道它可以工作,因为我在控制台中看到了“socket connect”,并且我还可以在最后测试套接字发出。

var myemail = "email@gmail.com";
var device_id = '12345';
// Create SocketIO instance, connect
var socket = io.connect('https://example.net:3000');

socket.on('connect', function(){
    try {
        console.log('socket connect');
        socket.emit('configure', {email:myemail, deviceid:device_id});
    } catch(e) {
        console.log(e);
    }
});
socket.emit("/" + device_id, "45678");

...下面是我从 node.js 实例运行时无法工作的代码。我希望命令行日志中有一条消息“套接字连接”,但什么也得不到。

var express=require('express');
var http=require('http');
var app=express();
var server = http.createServer(app);
//Variables

var myemail = "email@gmail.com";
var device_id = '12345'; 

var io = require('socket.io-client');
var socket = io.connect('https://example.net:3000');

//Connect listener
socket.on('connect', function(){
   try {
      console.log('socket connect');
      socket.emit('configure', {email:myemail, deviceid:device_id});
   } catch(e) {
     console.log(e);
   }
});
socket.emit("/" + device_id, "45678");

有什么想法吗?

更新

运行调试实用程序,结果如下图所示。我看到的关键是 engine.io 尝试进行 xhr 轮询,并从服务器返回 503 响应。 (显然,服务器再次出现真正的“临时错误”,这一切都可以通过在 chrome 中运行客户端 js 来实现)。

debugging output image link

【问题讨论】:

  • 这是一个猜测。如果您想要在connect 事件中执行您的socket.emit("/" + device_id, "45678");,会发生什么情况。您正在尝试在连接完成之前.emit()。也许这不会在浏览器中引起问题,而是在 node.js 上?也许这两个平台上的时间可能不同。
  • 哦,顺便说一句,socket.io-client 在 node.js 中工作得很好,可以连接到其他 socket.io 服务器,所以这不是问题。
  • 仅供参考,socket.io 有各种调试模式,可以让您非常详细地记录正在发生的事情。这可能会说明正在发生的事情。
  • 感谢 jfriend00 的回复。尝试将发射添加到 on.("connect") 函数中,但没有奏效 - 无论如何,这是在 on connect 函数中已经存在的初始握手发射不起作用。 ... 还尝试使用服务器的 IP 而不是名称。关于调试模式,对我应该寻找什么有任何想法?我可以看到它没有连接,但不确定要查找什么。
  • 您确定您的服务器上有正确版本的 socket.io-client 来匹配您要连接的内容吗? socket.io 对匹配客户端和服务器版本可能很挑剔。我不知道 socket.io 中的调试信息不​​知道要查找什么。如果你想在某处发布所有调试输出,我会看看它。

标签: javascript node.js socket.io iot


【解决方案1】:

解决了这个问题 - 问题是我连接到的服务器需要使用 https,所以我需要添加

{secure: true,    rejectUnauthorized: false}

在要连接的 url 之后。

完整的工作示例:

const myemail   = email@email.com;
const device_id   = 12345;
io = require('socket.io-client');
var socket = io.connect('https://server.net:3000',{secure: true,    rejectUnauthorized: false});

function doStuff(){


//Listener
socket.on('connect', function(){
   try {
      console.log('socket connect');
      socket.emit('configure', {email:myemail, deviceid:device_id});

   } catch(e) {
     console.log(e);
   }
});

socket.emit("/" + device_id, "003021");


}


doStuff();

【讨论】:

    【解决方案2】:

    我认为导致问题的行是:

    var socket = io.connect('https://example.net:3000');
    

    我设法使用此代码制作了一个工作示例:

    const myemail = "email@gmail.com";
    const device_id = '12345'; 
    var socket = require('socket.io-client')('https://example.net:3000');
    socket.on('connect', function(){
     try{
       console.log('socket connect');
       socket.emit('configure', {email:myemail, deviceid:device_id});
     }catch(e){ console.log(e); }
    });
    

    【讨论】:

    • 这对我没有任何影响 - 我看到有一些人已经设法在他们自己的本地主机上完成这项工作。我的预感是它与在连接时传递给套接字的登录凭据(电子邮件和设备 ID)有关 - 由于某种原因,当我尝试执行服务器端时,这些凭据没有被接受......
    • 你为什么这么认为?您必须分部分进行,客户端是否与服务器握手? (您的服务器是否通知客户端连接?)您说它可以从 localhost 工作,但不能从其他机器工作? > 可能和防火墙有关?
    猜你喜欢
    • 1970-01-01
    • 2018-12-15
    • 2018-10-06
    • 2011-06-11
    • 1970-01-01
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多