Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using socket.io with sails js

While there used to be very good documentation for using sockets, thanks to Irl Nathon's Sails Cast series. Things have changed in v0.11, with the sails team wrapping and burying the socket.io routines.

The sails site e.g. SailsSocket is maddeningly concise, saying what to do, but not how or where to do it, or if I need to npm or bower something. This has been particularly frustrating trying to use the sails.config.sockets talked about on the sails site. Which I cannot even find in my v0.11 directories.

First, I would like to know how and where to create my own response to a io.socket.get or .post or whatever. Right now when I do a get with something like:

`io.socket.request({
  method: 'get',
  url: '/sites/2',
  params: {},
  headers: {}
},function serverResponded(body, JWR){console.log("Body: ", JSON.stringify(body,null, 4)); console.log(' JWR: ', JWR.body)});'

I get back:

undefined
VM1149:7 "Not implemented in core yet"
VM1149:7  JWR:  Not implemented in core yet

I can see the sites being called in the sails console, but nothing comes across.

I believe it is because I have defined my own routes and have my own find: function in my site controller and I manually need to push something into the server side socket. But I am confused as to how I am to call a whole page with HTTP and just the tables with socket.io in the same controller routine.

  • Where do I write my own low level socket.io routines that can be called from a web page?

  • Do I still do it in the app.js file?

Sails Cast showed it being done there, but again things have changed.

like image 293
user2728963 Avatar asked Sep 23 '15 23:09

user2728963


1 Answers

Sails "virtual requests" (what they call these socket.io-based HTTP-ish request) are generally used to retrieve or post JSON data to the server. Additionally, if a client-side script makes a virtual request, the server may add or remove the requesting socket to/from rooms.

Note that using a "virtual method" will ultimately run the same controller action, but will set req.isSocket = true.

This example is a view that renders a view for HTML-wanting requests but returns JSON data for socket-based requests:

...
// 'get /sites/:id': 'SomeController.showSite' (should be put in your `routes.js`)
showSite: function(req, res) {
  // load something from the database
  Site.findOne(req.param('id')).exec(function(err, site) {
    // handler errors (same for HTTP or sockets)
    if (err) return res.serverError();
    if (!site) return res.notFound();

    if (req.isSocket) return res.json(site); // render JSON response for our `site` object
    else return res.view('sites/show', {site: site}); // render an HTML view
  });
}

As for low-level socket.io, sails provides the global variable io (from sails.io.js), which is an instance of SailsSocket. It allows you to make HTTP-ish "virtual requests". More info here (although it seems you have already read all there is to read about SailsSocket :). You can access the underlying socket.io client with io.socket._raw.

// do this in the browser. 
// sails.io.js should be included in layout.ejs by default.
io.socket.get('/site/2', console.log); // "virtual request"
// neat little trick     ^^^^^^^^^^^     for testing :)
var rawIO = io.socket._raw;
rawIO.emit('some:event', "using native socket.io");

Hope this helps!

like image 81
ContinuousLoad Avatar answered Oct 25 '22 14:10

ContinuousLoad