是这样的, 我想把本来.Net的程序移植到Node上来, 现在碰到了一个问题, 以前通信都是同步的所以没什么问题, 但是现在异步了之后想了好久不知道怎么解决,希望大家能帮忙给点意见~~ 先假设整个系统分成三个部分,Server(后端处理器)、WebServer(网页后台以前.Net写的)、Web(前端网页)。 Sevrer和WebServer之间是通过TCP来通信的(之前一直是同步的),WebServer和Web之间用ajax通信,现在Web向WebServer请求一个值V, WebServer收到请求后, 再向Server发一条请求命令,然后WebServer收到Server返回值V, 再将V返回给Web端。 以前是同步的没什么问题, 都是等待返回, 但是现在如果在Node上,那我WebServer向Server发出请求后就返回了,这时候其实还没有收到Server的回复, 就返回给Web了。我也想过用回调的方式,如下的代码,当发送命令给Server端即调用下面的sendDmitc的时候都带一个回调函数(callback),然后在socket的data事件中会调用callback,这样处理一次连接是没什么问题, 但是如果第一次会话(callback1)还没有返回,第二次会话(callback2)就来了, 那么callback不就被设置成callback2了么, 一直想不到什么办法来处理这个问题, 希望大家帮忙给点意见, 谢谢~~
var net = require("net");
var parseString = require('xml2js').parseString;
var uuid = require("node-uuid");
var iccModels = require('./iccModels.js');
var Q = require('q');
var idleFunc = function (data, err) {
console.log('idle handle: ' + data);
};
var serverConnector = function (host, port) {
var self = this;
this.commandList = [];
this.host = host;
this.port = port;
//Socket接收完数据后都会调用这个回调
this.recvCallback = idleFunc;
this._bConnect = false;
this._session = new net.Socket();
this._session.setKeepAlive(true);
this._session.on('data', function (data) {
var err = '';
// 将Buffer的内容解析出来
var iccData = new iccModels.ICCData();
// 先提取前面两个字节, 表示类型
iccData.dataType = data.toString('utf-8', 0, 2);
// 再读取后面的四个字节表示正文长度
iccData.dataLength = data.readUInt32BE(2);
// 验证下长度是否正确
if ((data.length - 6) != iccData.dataLength) {
err = '接收的数据不完整';
} else {
// 根据类型的不同分开处理
switch (iccData.dataType) {
case 'TX':
// 解析文本数据
var xml = data.toString('utf-8', 6);
self.parseTXData(xml).then(function (result) {
iccData.txDataValue = result.DMITC;
self.recvCallback(iccData, err);
});
break;
case 'BS':
break;
case 'ER':
break;
default:
err = '接收到未知类型数据';
}
}
});
this._session.on('error', function (err) {
console.log('socket error: ' + err);
});
this._session.on('close', function () {
console.log('connection closed');
self._bConnect = false;
});
};
serverConnector.prototype.sendDmitc = function (dmitc, callback) {
var self = this;
try {
// 先设置成功回调
self.recvCallback = callback || idleFunc;
var funcSend = function (data) {
var send_dmitc = data.toXml();
var sendBuffer = new Buffer(send_dmitc.length + 6);
sendBuffer.write('TX', 0, 2, 'utf-8');
sendBuffer.writeInt32BE(send_dmitc.length, 2);
sendBuffer.write(send_dmitc, 6, send_dmitc.length, 'utf-8');
console.log(sendBuffer);
// send
self._session.write(sendBuffer);
};
if (!this._bConnect) {
this._session.connect(this.port, this.host, function () {
self._bConnect = true;
console.log('Connect successful! host: ' + self.host + ' port: ' + self.port);
funcSend(dmitc);
});
} else {
funcSend(dmitc);
}
} catch (e) {
console.error(e);
}
};
serverConnector.prototype.parseTXData = function (xmlData) {
var deferred = Q.defer();
parseString(xmlData, {explicitArray: false}, function (err, result) {
deferred.resolve(result);
});
return deferred.promise;
};
然后下面是请求:
/**
* 客户端登录命令
* */
var DMITC_Login = function (dataSource, userId, passWord) {
this._dmitc = new DMITC('Login', 'post');
this._dmitc.addParameter('Datasource', 'string', dataSource);
this._dmitc.addParameter('UserID', 'string', userId);
this._dmitc.addParameter('Password', 'string', passWord);
};
DMITC_Login.prototype.exec = function (serverConn, callback) {
serverConn.sendDmitc(this._dmitc, function (data) {
// 这个时候已经是接收完数据了
var returnStatus = GetReturnStatus(data.txDataValue);
if (callback) {
callback(returnStatus);
}
});
};
6 回复