Nodejs 使用Transform的问题
Nodejs 使用Transform的问题
使用Transform时,第一次可以从socket接收到客户端数据(HTTP请求),等处理并写入socket一些响应数据后,想再次处理客户端数据时,但获取不到任何数据,使用模式: var Transform = require(“stream”).Transform; var inherits = require(“util”).inherits; var Request = function() { Transform.call(this); this._transform = function(data) { console.log("recv data length " + data.length); // 这一句只处理了一次 }; }; inherits(Request, Transform);
net.createServer(function(socket) { var req = new Request(); socket.pipe(req).pipe(socket); }); 在浏览器中检查socket使用状态,在发送HTTP请求后,后续数据是发送出去的(数据发送在onopen中),客户端已经发送成功,连接也还在,说明服务器socket已经收到数据了,从Readable的角度看,是监听src的’data’事件,如果Request没有收到数据,是不是可以说src没有触发’data’事件?或者说监听src失效?
代码标记一下吧
标记代码?网页自带的编辑器没有提供代码高亮啊! 代码是临时手敲的,不多也很简单,凑合着看吧~~~ 如果我不用这种方式,换一种思路,将: var req = new Request(); socket.pipe(req).pipe(socket); 换成是: Request.prototype.on(“request”, function(data) { … }); var req = new Request(); req.pipe(socket); socket.on(“readable”, function(data) { var data = socket.read(); req.emit(“request”, data); }); 之后测试代码,运行正常! 'readable’事件以被动方式取数据,就更加证实了上面的推测!
var data = socket.read(); req.emit(“request”, data); 应该是: var data = socket.read(); data && req.emit(“request”, data);
当你使用 Transform
流来处理从客户端通过 socket
接收到的数据时,可能会遇到多次调用 _transform
方法的问题。这是因为 Transform
流默认情况下会消耗输入数据,并且可能需要特殊处理才能多次接收数据。
以下是一个示例代码,展示了如何正确使用 Transform
流来处理从客户端接收到的数据,并能够多次接收这些数据:
const { Transform } = require('stream');
const net = require('net');
class CustomTransform extends Transform {
constructor() {
super({ readableObjectMode: true });
this.pushedData = [];
}
_transform(chunk, encoding, callback) {
console.log(`Received chunk: ${chunk.length} bytes`);
// 将接收到的数据缓存起来
this.pushedData.push(chunk);
// 处理完数据后调用回调函数
callback();
}
// 实现_flush方法来处理剩余的数据
_flush(callback) {
if (this.pushedData.length > 0) {
console.log(`Flushed ${this.pushedData.length} chunks of data`);
// 将所有缓存的数据合并并推送出去
this.push(Buffer.concat(this.pushedData));
}
callback();
}
}
const server = net.createServer((socket) => {
const transformStream = new CustomTransform();
socket.pipe(transformStream).pipe(socket);
});
server.listen(3000, () => {
console.log('Server is listening on port 3000');
});
解释
-
CustomTransform 类:继承自
Transform
,重写了_transform
和_flush
方法。_transform
方法用于处理每个传入的chunk
,并将数据缓存到pushedData
数组中。_flush
方法用于在流结束时处理缓存的数据。如果pushedData
数组中有数据,则将其合并并推送出去。
-
创建服务器:使用
net.createServer
创建一个 TCP 服务器,并将客户端的socket
管道到CustomTransform
流,然后再管道回socket
。 -
启动服务器:在端口
3000
上启动服务器。
这样处理之后,即使客户端多次发送数据,_transform
方法也能被多次调用,从而能够多次处理数据。