使用protobuf 塞到buffer里,然后自己写转换。需要处理粘包,5年前我第一个项目就是这么做的。5年前的代码了,你凑活凑活看吧,
function GameMain(aPort,aCallback){
var mCenterSocket = mNet.createConnection(aPort,'127.0.0.1');
/** 连接成功 */
mCenterSocket.on('connect', function() {
mProcessingLogic.SetSocket(mCenterSocket);
mProcessingLogic.EfficacySocket();
mLogger.ConsoleLog("Connected to GateServer at port: " + aPort);
});
var tBuffer = new mPackageSystem.exPackag(onReceivePackData);
/** 接收数据的方法 */
mCenterSocket.on('data', function(data) {
tBuffer.putData(data);
});
/** 连接断开 */
mCenterSocket.on('close', function(data) {
mLogger.ConsoleLog('GateServer connection closed');
setTimeout(function(){
mLogger.ConsoleLog('GateServer reconnecting...');
mCenterSocket.connect(aPort,'127.0.0.1');
},3000);
});
/** 连接的异常 */
mCenterSocket.on('error', function(error) {
mLogger.ConsoleLog('GateServer connection error');
});
/** 一个完整的包 */
function onReceivePackData(aBuffer){
aBuffer=new Buffer(aBuffer);
var tObj=mCommon.getServerBag(aBuffer);
if(tObj!=null)
{
mLogger.ConsoleLog("===== UID:" + tObj.Obj.uid + " " + tObj.MessageName);
mRouter.RouteSocket(tObj);
}
else
{
mLogger.ConsoleLog("消息验证失败");
}
}
aCallback(null, null);
}
------------------------------------mPackageSystem.js--------------------------------------------
function exPackag(aCallback)
{
this.mBuffer = new Array();// 缓冲容器
this.mBuffer_len = 0;// 协议长度
this.mData_len_Median = 2;// 协议的长度所占的位数
this.mCallback = aCallback;// 回调函数
}
exPackag.prototype.putData = function(aData)
{
//mLogger.ConsoleLog("PS putData: " + aData.length);
if (this.mBuffer_len == 0) {
if (aData.length < this.mData_len_Median) {
mLogger.SetDebug('包头不全直接忽略');
return;
} else {
this.mBuffer_len = getIntToByte16(aData) + this.mData_len_Median;
}
}
for (var index = 0; index < aData.length; index++) {
this.mBuffer.push(aData[index]);
}
if (this.mBuffer_len == -1) {
this.mBuffer_len = getIntToByte16(this.mBuffer) + this.mData_len_Median;
}
while (this.mBuffer_len > 0) {
/** 如果缓存中的长度刚好是一个包的长度 */
if (this.mBuffer.length == this.mBuffer_len) {
//mLogger.ConsoleLog('刚好是一个包');
this.mCallback(this.mBuffer);
this.mBuffer = null;
this.mBuffer = new Array();
this.mBuffer_len = 0;
return;
}
/** 如果缓存中的长度大于一个包的长度 */
else if (this.mBuffer.length > this.mBuffer_len) {
//mLogger.ConsoleLog('大于一个包,包头长度:' + this.mBuffer_len + ',实际长度:' + this.mBuffer.length);
/** 先获取一个完整的包 */
var tBuffer = this.mBuffer.splice(0, this.mBuffer_len);
this.mCallback(tBuffer);
tBuffer = null;
if (this.mBuffer.length >= this.mData_len_Median) {
this.mBuffer_len = getIntToByte16(this.mBuffer) + this.mData_len_Median;
} else {
this.mBuffer_len = -1;
}
} else {
/** 不满足长度 */
//mLogger.ConsoleLog('不满足长度,包头长度:' + this.mBuffer_len + ',实际长度:' + this.mBuffer.length);
this.mBuffer_len = -1;
return;
}
}
};
function getIntToByte16(aRecv)
{
var targets = (aRecv[0] & 0xff) | ((aRecv[1] << 8) & 0xff00);
return targets;
}
exports.exPackag = exPackag;
-----------------------------------------------------压缩部分-----------------------------------------
//aData是protobuf结构
function serializedServerBag(aData)
{
aData=JSON.stringify(aData);
aData=new Buffer(aData);
var tMessageDataLen=aData.length;
var tValue=getByteToInt16(tMessageDataLen);
var tBuf=Array();
tBuf=tBuf.concat(tValue);
for(var index=0; index<aData.length; index++) {
tBuf.push(aData[index]);
}
return tBuf;
}