2

我花了很长时间尝试将 Socket.IO-Client 连接到在 Sails.js 框架上运行的服务器。客户端基本上是一个在 Raspberry Pi 上使用 Node.js 运行的简单 JavaScript 应用程序。

这个想法是一个简单的设备连接到一个服务器,然后服务器注册该设备并订阅它的消息。设备从服务器接收消息并执行一些操作。我不希望客户端依赖于任何框架,因此,我试图避免使用 Sailsjs-socket.io-client。目前服务器和客户端都在我的本地机器上运行。这是代码:

// Server side. Sails.js. DevicesController.js

module.exports = {

  handshake: function (req, res) {
    if (!req.isSocket) return res.badRequest();
    Devices.create({}).exec(function (error, data) {
      Devices.subscribe(req.socket, data);
    });
    return res.ok();
  }

};


// Client side
var socket = require('socket.io-client')('http://localhost:1337/devices/handshake');

socket.on('error', function(e) {
    console.log(e);
    // Here I get 'Invalid namespace'
});

所以,我在客户端收到错误“无效的命名空间”,如果我是对的,这意味着服务器没有打开“/devices/handshake”。但是,在服务器端,如果我列出现有房间 ID (sails.sockets.rooms()),我可以看到当客户端尝试连接到服务器时,总是会创建一个新房间。

我尝试使用下面的 javascript 从浏览器连接到“/devices/handshake”,显然它有效。它显然与 Sailsjs-socket.io-client 一起运行。

io.socket.get('/devices/handshake', function (data, jwres) {
  console.log(jwres);
});
io.socket.on('devices', function (data, jwres) {
  console.log(data);
});

任何想法我做错了什么?

4

1 回答 1

6

您似乎在这里混淆了一些概念:即 Socket.io 命名空间、Socket.io 路径和 Sails 路由。您可以通过查看Socket.io 文档了解更多关于前两个的信息。就 Sails 而言,要记住的主要事情是它只侦听默认/命名空间上的连接。因此,您应该始终将客户端套接字连接到:

var socket = require('socket.io-client')('http://localhost:1337');

添加/devices/handshake到末尾不会更改套接字尝试连接的 URL;它总是会尝试连接到http://localhost:1337/socket.io. 相反,这意味着它将尝试使用/devices/handshakeSails 未提供的名称空间注册套接字。

另一方面,当您调用 时,您正在使用 Sails 套接字客户端库向您的应用程序中的该路由io.socket.get('/devices/handshake')发出虚拟请求,就像您使用 AJAX(例如在 jQuery 中)一样。这正是创建的原因——它使这类事情变得非常容易!它也没有真正把你束缚在前端。所做的只是提供一些包装器,以便通过套接字与 Sails 后端进行通信。在幕后,它只是简单地使用 Socket.io-client方法向服务器发送事件,其中包含描述要运行的 Sails 操作的 URL 和参数的有效负载。所以这:$.get('/devices/handshake')sails.io.jssails.io.jsio.socket.get.emit()get

io.socket.get('/devices/handshake', function(body, res){...})

相当于连接你自己的socket并这样做:

socket.emit('get', {url: '/devices/handshake'}, function(res){...})

在第一次连接时运行套接字逻辑的推荐方法是允许套接字在客户端上完全连接,然后从客户端向服务器发出请求(正是您在第二个代码块中所做的)。要详细了解这背后的原因,请参阅Sails 0.11.x 迁移指南中的此说明。该注释还解释说,如果由于某种原因您必须在服务器连接后立即运行逻辑,您可以这样做

sails.io.on('connect', function (newlyConnectedSocket){}) 

在您的引导函数 ( config/bootstrap.js) 中。

于 2016-02-04T16:01:00.103 回答