Search code examples
node.jssocketstcpnode-streams

How do I intercept outgoing tcp messages in node?


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


Solution

  • 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.