在做flash游戏开发和服务器内网rpc通信的时候,经常使用的是4个字节的包头,这4个字节描述了包体的长度,包体一般是json文本数据,如果是rpc可能是二进制数据。
在erlang的网络库中对这种分包方式有底层库原生支持,在java的mina,netty网络库中也有支持,在node.js中需要我们自己来处理分包问题,还好githup上已经有了这样一个模块head_body_buffers模块,我们直接拿来用就好了,非常方便,具体请看https://github.com/freedaxin/head_body_buffers。下面直接上代码,基于这种分包协议的简单服务器端和客户端代码
<
/**
* User: dq
* Time: 13-6-28 上午10:04
*/
var net = require('net');
var HeadBodyBuffers = require('./lib/head_body_buffers').HeadBodyBuffers;
function packetLength(data) {
return data.readUInt32BE(0);
}
var server = net.createServer(function(connection) { //’connection’ listener
console.log('new socket connected ');
connection.setTimeout(2601000);
connection.setNoDelay(true);
var hdb = new HeadBodyBuffers(4, packetLength);
hdb.on('packet’, function (packet) {
var head = packet.slice(0, 4);
var body = packet.slice(4);
console.log("body:", body.toString(), body.length);
connection.write(packet);
});
connection.on('end', function() {
console.log('socket '+ connection +" closed ");
});
connection.on('data',function(data){
hdb.addBuffer(data);
});
connection.on('timeout',function(){
connection.end();
})
connection.on('error',function(error){
console.error(error);
connection.end();
})
});
server.listen(11000, function() {
console.log(‘server start’);
});
server.on('error’,function(error){
console.error(error);
})
// simple client test
var client = net.connect(11000);
var hbd = new HeadBodyBuffers(4, packetLength);
hbd.on('packet’, function (packet) {
var head = packet.slice(0, 4);
var body = packet.slice(4);
console.log("body:", body.toString(), body.length);
client.write(packet);
})
var keepAlive = '{type:"keepAlive"}’;
var packet = new Buffer(4+ Buffer.byteLength(keepAlive));
packet.writeUInt32BE(Buffer.byteLength(keepAlive),0);
packet.write(keepAlive,4);
client.write(packet);
client.on('data’, function(data) {
hbd.addBuffer(data);
});