Nodejs作为通过套接字的请求/响应服务器的客户端

时间:2014-07-21 18:03:40

标签: node.js sockets request client sails.js

我正在尝试使用sailsjs构建一个Web服务器。

为了执行请求,我的服务器需要连接到套接字以传递命令并等待响应。

对于每个命令,我等待特定的响应并且必须调用特定的回调。目前我只打开一个套接字并在每个请求时更改“onData”套接字。它看起来效果不好而且很难看。

另一种选择可能是为每个命令或请求打开和关闭套接字:我发现它甚至更糟。

有一种聪明的方法可以做我需要的吗?

编辑:

这是套接字(DriverConnection.js):

module.exports = {

    connect: function(callback){
        var net = require('net');
        client = net.connect({port: 13}, function() { //'connect' listener
            console.log('client connected');
            callback();
        });
    },

  command: function(command, callback){
    client.write(command);
    client.on('data', function(data) {
      console.log("parsing data " + data.toString());
      callback(JSON.parse(data.toString()));
    });
  }

};

以下是其请求用法的示例:

module.exports = {

    list: function(req,res) {
      DriverConnection.command('{}',function(data){
        for(key in data) {
          var mac = data[key];
          Autoreez.findOne({name : mac},function (err,auto){
            if(!auto) {
              User.create({name : mac}, function(err,user){
                res.send(user);
              });
            } else {
              res.send(auto);
            }
          });
        }
      });
    },
}

1 个答案:

答案 0 :(得分:1)

一种可能的解决方案是创建响应路由器,根据请求名称触发特定回调。

由于 net 模块本身不支持此类行为,因此您需要使用某种库或使用(例如)EventEmitter编写自己的路由器。

第1步

创建驱动程序服务: api / services / DriverService.js

var net = require('net');
module.exports = {
    connection: null,

    // open connection
    connect: function(cb) {
        var self = this;

        this.connection = net.connect({ port: 13 }, cb);

        // response router
        this.connection.on('data', function(data) {
            var res = JSON.parse(data.toString());
            self.connection.emit(res.req, res.msg);
        });
    },

    // close connection
    disconnect: function() {
        this.connection.end();
    },

    command: function(cmd) {
        this.connection.write(cmd);
        // return an instance of event emitter
        return this.connection;
    }
};

第2步

接下来,在sails应用程序启动时连接到套接字服务器,在停止时断开连接。

// config/bootstrap.js
module.exports.bootstrap = function(cb) {
    // connect to service
    DriverService.connect(cb);
};

// config/teardown.js
module.exports.beforeShutdown = function(cb) {
    // disconnect from service
    DriverService.disconnect();
    cb();
};

第3步

修改套接字服务器以发送带请求名称的响应。

// ...
socket.on('data', function (data) {
    var reqName = data.toString();
    socket.write(JSON.stringify({ req: reqName, msg: 'some response' }));
});
// ...

第4步

现在,您可以将任何类型的回调绑定到特定请求。

如果您愿意,可以在DriverService中绑定它们(在 connect()函数中) 或动态地在您的应用程序控制器中,如下所示:

API /服务/ DriverService.js

this.connection
    .on('data', function(data) {
        var res = JSON.parse(data.toString());
        self.connection.emit(res.req, res.msg);
    })
    .on('list', function(data) { /* ... */ })
    .on('add', function(data) { /* ... */ })

OR

API /控制器/ SomeController.js

module.exports = {
    list: function(req, res) {
        DriverService.command('list')
            .once('list', function(data) {
                console.log('callback for list request');
                res.send(data);
            })
            .once('add', function(data) {
                console.log('callback for add request');
                res.send(data);
            });
    }
}

如果在控制器中绑定,则必须使用 once()来阻止绑定多个事件侦听器。

希望有所帮助。