假如我们有这样一个程序:
为了实现数据交互,服务器向客户端不断地发送JSON数据,在流中传输之前转化JSON字符串格式(JSON.stringify),客户端也不断地得接受并解析(JSON.parse)字符串。
这个过程看起来再正常不过了。
但是实际上这里有个难以察觉的漏洞:
理想情况下,每一条消息每次都接收成功,但有时候消息可能被切分成几块数据,进而被多次解析json。当情况为后者的时候,解析肯定是失败的。
这个时候,我们就要为“解析”这个步骤专门设计出应对这种情况的代码。
由于不同的编程语言都有可能出现这样一种情况,这里以Node.js为例,为json的处理编写一个特殊方案:
编写一个专门处理应对分段数据发送的客户端,这里仅用来讲解客户端是怎么处理的,并非实际生产中的客户端代码。
解释一下:客户端是以\n为每组JSON字符串的结束标识符。
//自定义模块,客户端(避免一条JSON字符串被拆分发送后parse转化异常)
/**
* 服务端是这么发送数据的
* connection.write(JSON.stringify({type:'watching',filename:filename})+'\n');
*/
'use strict';
const EventEmitter = require('events').EventEmitter;
class MyClient extends EventEmitter{
constructor(stream){
super();
let buffer = '';
stream.on('data',data=>{
//将每次传输的数据添加到缓冲区中
buffer+=data;
//检测\n首次出现的位置,如果不存在则返回-1
let boundary = buffer.indexOf('\n');
//当判断到存在\n时
while(boundary!== -1){
//将本行字符串保存下来
const input = buffer.substring(0,boundary);
//剩余字符串到缓冲区中
buffer = buffer.substring(boundary+1);
//立即触发事件
this.emit('message',JSON.parse(input));
//再次判断是否出现了/n
boundary = buffer.indexOf('\n');
}
})
};
//创建一个静态的方法,方便使用者快速创建实例
static connect(stream){
return new MyClient(stream);
}
}
module.exports=MyClient;