我正在尝试使用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);
}
});
}
});
},
}
答案 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()来阻止绑定多个事件侦听器。
希望有所帮助。