How can I write a simple stream which intercepts messages?
For example, say I want to log (or eventually transform) a message being sent over the wire by a user's socket.write(...) call.
Following is a minimal program which attempts to do this:
const net = require('net');
const stream = require('stream');
const socket = new net.Socket();
const transformer = new stream.Transform({
transform(chunk,e,cb){
console.log("OUT:"+chunk.toString());
cb();
}});
//const client = socket.pipe(transformer); // <= prints "OUT:" on client, but nothing on server
const client = transformer.pipe(socket); // <= prints nothing on client, but "hello world" on server
socket.on('data', (data)=>{ console.log("IN:"+data.toString()); });
socket.connect(1234, 'localhost', ()=>{ client.write("hello world"); });
When I do socket.pipe(transformer), the client prints "OUT:" (like I want), but doesn't actually send anything to the server. When I swap the pipe locations, transformer.pipe(socket), nothing gets printed to the client but the message gets sent to the server.
Although not listed here, I also tried to use the Writable stream, which does print the message on the client, but it is never sent to the server (if I do a this.push(...) inside the Writable stream, it still doesn't seem to send to the server)
What am I missing here?
EDIT: Reformatted the code for clarity and updated the text
It looks like I needed to change the following line
socket.connect(1234, 'localhost', ()=>{ client.write("hello world"); });
to this
socket.connect(1234, 'localhost', ()=>{ transformer.write("hello world"); });
This is based on @Mr.Phoenix's comment. I expected .pipe() to return a new stream which I could use. I believe that is how Java's netty framework does it and I kept expecting node streams to work the same way.
You're not writing any data out of the stream.
You need to either this.push(chunk) or change the call to cb to cb(null, chunk).
See the docs about implementing transform streams for more info.