5

As a part of an ongoing effort, I'm changing my current callbacks technique to promises using blue-bird promise library.

I would like to implement this technique with Socket.IO as well.

  • How can I use Socket.IO with promises instead of callbacks?
  • Is there any standard way of doing it with Socket.IO? any official solution?
Eran Betzalel
  • 4,105
  • 3
  • 38
  • 66
  • If you are not strongly stuck to Socket.IO, you may consider plain websockets wrapped into promises. See https://stackoverflow.com/questions/42304996/javascript-using-promises-on-websocket – vitalets Sep 29 '17 at 08:04

3 Answers3

3

You might look into Q-Connection, which facilitates RPC using promises as proxies for remote objects and can use Socket.IO as a message transport.

Kris Kowal
  • 3,866
  • 2
  • 24
  • 24
1

Bluebird (and many other promise libraries) provide helper methods to wrap your node style functions to return a promise.

var readFile = Promise.promisify(require("fs").readFile);

readFile("myfile.js", "utf8").then(function(contents){ ... });

https://github.com/petkaantonov/bluebird/blob/master/API.md#promisification

Returns a function that will wrap the given nodeFunction. Instead of taking a callback, the returned function will return a promise whose fate is decided by the callback behavior of the given node function. The node function should conform to node.js convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument.

Scott Puleo
  • 3,684
  • 24
  • 23
  • Sure, I know that, but I'm looking for an official support for socket.io/promises like mongoose's `exec()` which returns `Promise` object. – Eran Betzalel Feb 14 '14 at 00:18
  • 2
    Gotcha. Most websocket modules use evented api's. It is easy to convert a callback based api to promises, less so with something that uses eventemitter. – Scott Puleo Feb 14 '14 at 00:42
1

have a look here https://www.npmjs.com/package/socket.io-rpc

var io = require('socket.io').listen(server);
var Promise = require('bluebird');
var rpc = require('socket.io-rpc');

var rpcMaster = rpc(io, {channelTemplates: true, expressApp: app})
        //channelTemplates true is default, though you can change it, I would recommend leaving it to true,
        //                   false is good only when your channels are dynamic so there is no point in caching
    .expose('myChannel', {
    //plain JS function
    getTime: function () {
        console.log('Client ID is: ' + this.id);
        return new Date();
    },
    //returns a promise, which when resolved will resolve promise on client-side with the result(with the middle step in JSON over socket.io)
    myAsyncTest: function (param) {
        var deffered = Promise.defer();
        setTimeout(function(){
            deffered.resolve("String generated asynchronously serverside with " + param);
        },1000);
        return deffered.promise;
    }
});


io.sockets.on('connection', function (socket) {
    rpcMaster.loadClientChannel(socket,'clientChannel').then(function (fns) {
        fns.fnOnClient("calling client ").then(function (ret) {
            console.log("client returned: " + ret);
        });
    });

});
ppalles
  • 51
  • 5