How to connect Socket.IO-Client to a Sails.js server?

I spent a lot of time trying to connect Socket.IO-Client to a server running on the Sails.js framework. The client is basically a simple JavaScript application that works with Node.js on a Raspberry Pi.

The idea is that a simple device connects to the server, then the server registers the device and signs it for messages. The device receives a message from the server and performs some actions. I do not want the client to depend on any structure, and for this reason I try to avoid using Sailsjs-socket.io-client. Currently, both the server and the client are running on my local computer. 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 does not have "/ devices / handshake". However, on the server side, if I list the existing room identifiers (sails.sockets.rooms ()), I see that a new room is always created when a client tries to connect to the server.

I tried to connect to "/ devices / handshake" from a browser with javascript below and apparently worked. Obviously, it works with the 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 I'm doing wrong?

+2
source share
1 answer

You seem to be confusing a few concepts here: the Socket.io namespace, Socket.io paths, and Sails routes. You can learn a little more about the first two by looking at Socket.io docs . The main thing to keep in mind with regard to Sails is that it only listens for connections in the default / namespace; therefore, you should always connect client sockets with:

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

Adding /devices/handshake to the end does not change the URL that the socket is trying to connect to; it will always try to connect to http://localhost:1337/socket.io . Instead, this means that it will try to register a socket with the namespace /devices/handshake , which Sails does not provide.

On the other hand, when you call io.socket.get('/devices/handshake') , you use the Sails socket client library to make a virtual request for this route in your application, just as if you were using AJAX ( e.g. $.get('/devices/handshake') in jQuery). That is why sails.io.js was created - it makes it very simple! It also does not bind you to the interface; all sails.io.js does provide some wrappers to make it easy to interact with Sails backends through sockets. Under the covers, io.socket.get simply uses 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 be performed. So this is:

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

equivalent to plugging in your own socket and doing this:

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

The recommended approach to start the logic for the socket when it is first connected is to allow the socket to fully connect to the client, and then make a request from the client to the server (exactly what you do in the second code block). To learn more about this, see this note in the Sails 0.11.x migration guide . This note also explains that if you must start the logic immediately after connecting to the server for any reason, you can do

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

in your bootstrap ( config/bootstrap.js ).

+5
source share

All Articles