node.js - Simple multiplexing node.js stream - chunk concatenated issue
问题描述
Im trying to implement a simple node.js stream multiplexer/demultiplexer.
Currently while implementing the multiplexing mechanism i noticed that the output of the multiplexer gets concatenated into a single chunk.
const { PassThrough, Transform } = require("stream");
class Mux extends PassThrough {
constructor(options) {
super(options);
}
input(id, options) {
let encode = new Transform({
transform(chunk, encoding, cb) {
let buf = Buffer.alloc(chunk.length + 1);
buf.writeUInt8(id, 0);
chunk.copy(buf, 1);
cb(null, buf);
},
...options
});
encode.pipe(this);
return encode;
};
};
const mux = new Mux();
mux.on("readable", () => {
console.log("mux >", mux.read())
});
const in1 = mux.input(1);
const in2 = mux.input(2);
in1.write(Buffer.alloc(3).fill(255));
in2.write(Buffer.alloc(3).fill(127));
Output looks like this: mux > <Buffer 01 ff ff ff 02 7f 7f 7f>
.
I would have thought that i receive two console.log
outputs.
Expected output:
mux > <Buffer 01 ff ff ff>
mux > <Buffer 02 7f 7f 7f>
Can some one explains why i only get one "readable" event and a concatenated chunk from both inputs?
解决方案
Use the data
event and read from the callback:
The 'data' event is emitted whenever the stream is relinquishing ownership of a chunk of data to a consumer.
mux.on("data", d => {
console.log("mux >", d)
});
This now yields:
mux > <Buffer 01 ff ff ff>
mux > <Buffer 02 7f 7f 7f>
Why readable
is only emitted once is explained in the docs as well:
The 'readable' event will also be emitted once the end of the stream data has been reached but before the 'end' event is emitted.
data
and readable
behave differently. In your case readable
is never emitted until the end of the stream data has been reached, which returns all the data at once. data
is emitted on each available chunk.
推荐阅读
- visual-studio - 我可以解决“无法连接到 Web 服务器 'IIS Express'”,但它会在几天后返回。这是为什么?
- algorithm - 对于给定的中序和前序遍历,如何推导出这个公式的证明,以便为二叉树获得正确的孩子?
- amazon-web-services - AWS EKS 节点组“创建失败”:实例未能加入 kubernetes 集群
- android - 我想为某些滚动空间触发 OnScrollChangeListener
- javascript - 选择第一个复选框后选择所有复选框
- html - 从 R 中的 URL 链接网络抓取所需内容的问题
- r - 匹配 r 中的两列
- ruby-on-rails - 如何使用 Rails 在生产环境中设置 Sendgrid 入站解析?
- firebase - 如何将 Firebase 与 Admob 连接起来?
- matrix - 如何通过围绕相机位置旋转所有点来模拟 3D 空间中的相机旋转?