simpleproto 是一个 TCP 简单传输协议
在 Socket(TCP)连接中传输数据,如果不对数据包做特殊处理,可能出现如下所谓的粘包、拆包的问题:
// 发送方发送一个数据 sender.write(data); // 接收方通过以下方式接收的数据和发送的不一致 receiver.on('data', (data) => { console.log(data); })
simpleproto 通过对传输及接收的数据简单组包及解包解决上述问题:
// 发送方
const { encode } = require('simpleproto');
/**
* 包的格式
* --------------------------------
* 1B | 4B | length | 1B
* 0x2 | length | message | 0x5
* --------------------------------
*/
sender.write(encode(data));
// 接收方
const { decode } = require('simpleproto');
decode(receiver, (data) => {
// 获取发送过来的数据的buffer对象
console.log(data);
});
安装
npm i --save simpleproto
使用
启动一个 socket server 服务:
// server.js const net = require('net'); const { encode, decode } = require('simpleproto'); const noop = _ => _; const server = net.createServer((socket) => { socket.on('error', noop); decode(socket, (data) => { data = `${data}`; console.log('Server receive data length:', data.length); socket.write(encode(data)); }); }); server.listen(9999, () => { console.log(`server listening on ${server.address().port}.`); });
客户端代码:
为方便查看内部数据包传输请求,采用 socketx 将请求代理到本地 whistle
const { connect } = require('socketx'); const { encode, decode } = require('simpleproto'); (async () => { const proxy = { host: '127.0.0.1', port: 8899, }; const client = await connect({ host: '127.0.0.1', port: 9999, proxy, }); decode(client, (data) => { console.log('Client receive data length:', `${data}`.length); }); client.on('error', (e) => console.error(e)); setInterval(() => { const data = 'test123456'.repeat(1024 * 3); console.log('send data length:', data.length); client.write(encode(data)); }, 3000); })();
从运行结果及 whistle 抓包可以看成,客户端发送 30k 数据后,socket 连接虽然把这些数据拆成几个包,而通过 simpleproto
在客户端及服务端都可以正确的获取完整的数据包。
API
const { encode, decode, Decoder } = require('simpleproto');
encode(data)
对数据进行组包,data 可以为 buffer、string、object
decode(stream, cb)
stream 为数据流(socket、文件流等),每次接收到新的数据包都会触发 cb(data)
new Decoder([stream[, cb]])
解包类对象,构造方法可以传入 stream
和 cb
,功能同 decode(stream, cb)
;也可以用于解包非数据流的字节码:
const decoder = new Decoder(); decoder.onData = (data) => { console.log(data); }; decoder.write(buf);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论