使用Socket.IO从Node.js连接到外部服务器

4
背景:我有一个运行在本地主机上的 node.js 服务器(称之为 A 服务器),和一个运行 node.js 的外部服务器,地址是 https://example.net:3000(称之为 B 服务器)。我无法控制或访问 B 服务器(它是我家里的物联网设备的仪表盘站点),但我需要使用 socket.io 连接到它并发送特定的消息。
我可以轻松地从一个扁平的 javascript 文件(客户端)连接到它,但需要在服务器端运行它(最终目标是将其变成可以通过 HTTP 请求调用的东西);像如何使用 WebSockets 连接两个 node.js 服务器?之类的示例表明,我应该能够使用来自 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实例时无法正常工作的代码。 我期望在命令行日志中收到一个“socket connect”的消息,但什么也没得到。

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可以正常工作)。

调试输出图像链接


感谢jfriend00的回复。尝试将emit添加到on.("connect")函数中,但没有成功 - 无论如何,最初的握手emit已经在连接函数中了,但它并没有起作用。...还尝试使用服务器的IP而不是名称。关于调试模式,您有什么想法应该寻找什么?我可以看到它没有连接,但不确定要查找什么。 - Lee
你确定你的服务器上安装了与你尝试连接的socket.io-client版本相匹配的版本吗?socket.io在匹配客户端和服务器版本方面可能会很挑剔。我不知道socket.io中的调试信息,也不知道该查找什么。如果你想在某个地方发布所有的调试输出,我可以看一下。 - jfriend00
所有的WebSocket连接都是通过HTTP请求发起的。默认情况下,所有的socket.io连接都从HTTP轮询开始,然后尝试升级到WebSocket(这两者都需要HTTP来进行)。所以,当你说“不能使用HTTP”时,我感到非常困惑。那是什么意思?对我来说,那听起来像是一个问题。 - jfriend00
你添加的日志告诉我们客户端正试图与服务器建立 HTTP 轮询连接(作为建立 socket.io 连接的通常第一步),但是这个过程失败了。 - jfriend00
你关于凭证的另一个评论与这有什么关系? - jfriend00
显示剩余6条评论
2个回答

4
解决了这个问题 - 问题是我连接的服务器要求使用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();

1
我认为导致问题的行是:


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)有关,这些凭据在连接时传递给套接字 - 出于某种原因,当我尝试执行服务器端时,这些凭据没有被接受... - Lee
你为什么这样想?你需要分步进行,客户端是否与服务器握手?(你的服务器是否通知客户端连接?)你说它在本地主机上运行正常,但在其他机器上却不行?>也许这与防火墙有关? - EMX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接