2

Pretty simple node.js question. I want to extend the stream object to re-chunk the data that is coming in from a remote connection. I'm doing multiple telnets and sending commands to other servers, and they send back responses. It looks something like this.

> Hello, this is a command

This is the response to the command.
Sometimes it pauses here (which triggers the 'data' event prematurely).

But the message isn't over until you see the semicolon
;

What I'd like to do is instead of triggering the 'data' event at the pause, is wait for the ; and trigger a custom 'message' event.

I've read and reread this question, but I don't quite get it yet (partially because it's about a writable stream, and partially because I don't yet grok CoffeeScript).

EDIT: I guess I'm asking two things here:

  1. How do I extend/inherit the stream object that net.CreateConnection uses?
  2. Can I just extend the prototype.write to do a 'split' and re-'emit' each part?

Here's a snip of what I'm doing so far, but the chunking should be part of the stream, not part of the 'data' listener:

var net = require('net');

var nodes = [
        //list of ip addresses
];

function connectToServer(ip) {
        var conn = net.createConnection(3083, ip);
        conn.on('connect', function() {
                conn.write ("login command;");
        });
        conn.on('data', function(data) {
                var read =  data.toString();

        var message_list = read.split(/^;/m);

        message_list.forEach (function(message) {
                    console.log("Atonomous message from " + ip + ':' + message);
            //I need to extend the stream object to emit these instead of handling it here
            //Also, sometimes the data chunking breaks the messages in two,
                        //but it should really wait for a line beginning with a ; before it emits.
        });

        });
        conn.on('end', function() {
                console.log("Lost conncection to " + ip + "!!");
        });
        conn.on('error', function(err) {
                console.log("Connection error: " + err + " for ip " + ip);
        });
}

nodes.forEach(function(node) {
        connectToServer(node);
});

If I was using a raw stream, I guess it would be something like this (based on code I found elsewhere)?

var messageChunk = function () {
  this.readable = true;
  this.writable = true;
};

require("util").inherits(messageChunk, require("stream"));

messageChunk.prototype._transform = function (data) {

  var regex = /^;/m;
  var cold_storage = '';

  if (regex.test(data))
  {
    var message_list = read.split(/^;/m);

    message_list.forEach (function(message) {
      this.emit("data", message);
    });
  }
  else
  {
    //somehow store the data until data with a /^;/ comes in.
  }
}

messageChunk.prototype.write = function () {
  this._transform.apply(this, arguments);
};

But I'm not using a raw stream, I'm using the stream object in the net.createConnection object returns.

2
  • Can you post your code here, maybe? That'll make it much easier to help. Commented Mar 23, 2013 at 18:54
  • How's that? Anyone? I could be going about this the wrong way... Commented Apr 2, 2013 at 18:59

1 Answer 1

0

Don't use the _transform,_read,_write,or _flush functions you implement directly, those are for the internals of node to use.

Emit a custom event when you see the character ";" in your stream:

var msg = "";
conn.on("data",function(data)  {
  var chunk = data.toString();
  msg += chunk;
  if(chunk.search(";") != -1)  {
    conn.emit("customEvent",msg);
    msg = "";
  }
});
conn.on("customEvent",function(msg)  {
  //do something with your message
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.