简体   繁体   English

如何将Socket.IO-Client连接到Sails.js服务器?

[英]How to connect Socket.IO-Client to Sails.js server?

I've spent quite a while trying to connect Socket.IO-Client to a server running on Sails.js framework. 我花了很长时间尝试将Socket.IO-Client连接到在Sails.js框架上运行的服务器。 The client is basically a simple JavaScript application running with Node.js on Raspberry Pi. 客户端基本上是一个简单的JavaScript应用程序,在Raspberry Pi上与Node.js一起运行。

The idea is that a simple device connects to a server, the server then registers the device and subscribes it for messages. 这个想法是,一个简单的设备连接到服务器,然后服务器注册该设备并为其订阅消息。 The device receives a message from the server and performs some actions. 设备从服务器接收消息并执行一些操作。 I don't want the client to be dependant on any framework and, for that reason, I am trying to avoid using Sailsjs-socket.io-client. 我不希望客户端依赖于任何框架,因此,我试图避免使用Sailsjs-socket.io-client。 At the moment both server and the client are running on my local machine. 目前,服务器和客户端都在我的本地计算机上运行。 Here is the code: 这是代码:

 // 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' }); 

So, I get the error 'Invalid namespace' on the client side and, if I'm right, it means that the server doesn't have '/devices/handshake' open. 因此,我在客户端收到错误“无效名称空间”,如果我是对的,则意味着服务器没有打开“ / devices / handshake”。 However, on the server side if I list existing room ids (sails.sockets.rooms()), I can see that a new room is always created, when the client tries to connect to the server. 但是,在服务器端,如果我列出现有的会议室ID(sails.sockets.rooms()),则可以看到当客户端尝试连接到服务器时始终会创建一个新会议室。

I tried to connect to '/devices/handshake' from a browser with the javascript below and apparently it worked. 我尝试使用下面的javascript从浏览器连接到“ / devices / handshake”,显然可以正常工作。 It obviously runs with Sailsjs-socket.io-client though. 它显然可以与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); }); 

Any ideas what am I doing wrong? 有什么想法我做错了吗?

It seems that you're confusing a few concepts here: namely Socket.io namespaces, Socket.io paths and Sails routes. 似乎您在这里混淆了一些概念:Socket.io名称空间,Socket.io路径和Sails路由。 You can learn a bit more about the first two by looking through the Socket.io docs . 通过浏览Socket.io文档,您可以学到更多有关前两个方面的知识 The main thing to keep in mind as far as Sails is concerned is that it only listens for connections on the default / namespace; 就Sails而言,要记住的主要事情是,它侦听default /名称空间上的连接。 therefore, you should always connect client-side sockets with: 因此,您应始终将客户端套接字与:

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

Adding the /devices/handshake onto the end doesn't change the URL that the socket is attempting to connect to; /devices/handshake添加到末尾不会更改套接字尝试连接的URL; it will always try to connect to http://localhost:1337/socket.io . 它将始终尝试连接到http://localhost:1337/socket.io Instead, it means that it will try to register the socket with the /devices/handshake namespace, which Sails isn't providing. 相反,这意味着它将尝试向Sails未提供的/devices/handshake命名空间注册套接字。

On the other hand, when you call io.socket.get('/devices/handshake') , you're using the Sails socket client library to make a virtual request to that route in your app, just as if you'd used AJAX (eg $.get('/devices/handshake') in jQuery). 另一方面,当您调用io.socket.get('/devices/handshake') ,您正在使用Sails套接字客户端库向应用程序中的该路由发出虚拟请求,就像您曾经使用过AJAX(例如jQuery中的$.get('/devices/handshake') )。 This is precisely why sails.io.js was created--it makes this sort of thing very easy! 这就是为什么创建sails.io.js原因-它使这种事情变得非常容易! It's also not really tying you down on the front-end; 它也并没有真正把您束缚在前端上。 all sails.io.js does is provide some wrappers to make it easy to communicate with Sails backends via sockets. sails.io.js所做的全部工作就是提供一些包装,以sails.io.js通过套接字与Sails后端进行通信的过程。 Under the covers, io.socket.get is simply using the Socket.io-client .emit() method to send a get event to the server, with a payload describing the URL and parameters of the Sails action to run. io.socket.getio.socket.get只是使用Socket.io-client .emit()方法将get事件发送到服务器,并带有描述URL和运行Sails操作参数的有效负载。 So, this: 所以这:

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

is equivalent to connecting your own socket and doing this: 等效于连接您自己的套接字并执行以下操作:

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

The recommended approach for running logic for a socket when it first connects is to allow the socket to connect fully on the client, and then make a request from the client to the server (exactly what you're doing in your second code block). 建议在套接字第一次连接时为该套接字运行逻辑的方法是允许该套接字在客户端上完全连接,然后从客户端向服务器发出请求(正是您在第二个代码块中所做的事情)。 To read more about the reasoning behind this, see this note in the Sails 0.11.x migration guide . 要了解有关其背后原因的更多信息,请参阅Sails 0.11.x迁移指南中的此注释 That note also explains that if you must run the logic immediately upon server connection for some reason, you can do 该注释还说明,如果由于某种原因必须在服务器连接后立即运行逻辑,则可以执行

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

in your bootstrap function ( config/bootstrap.js ) . 在您的引导功能( config/bootstrap.js )中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM