在node.js中“重新分块”Stream对象

时间:2013-03-22 22:34:28

标签: node.js stream

非常简单的node.js问题。我想扩展流对象以重新分块从远程连接进入的数据。我正在做多个telnet并向其他服务器发送命令,然后发回响应。它看起来像这样。

> 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
;

我想做的不是在暂停时触发'数据'事件,而是等待;并触发自定义的“消息”事件。

我已阅读并重新阅读this question,但我还没有完全理解它(部分原因是因为它是关于可写流的,部分是因为我还没有使用CoffeeScript)。

编辑:我想我在这里问两件事:

  1. 如何扩展/继承net.CreateConnection使用的流对象?
  2. 我可以将prototype.write扩展为“拆分”并重新发送每个部分吗?
  3. 这是我到目前为止所做的事情,但是分块应该是流的一部分,而不是“数据”监听器的一部分:

    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);
    });
    

    如果我使用原始流,我猜它会是这样的(根据我在别处找到的代码)?

    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);
    };
    

    但是我没有使用原始流,我正在使用net.createConnection对象返回的流对象。

1 个答案:

答案 0 :(得分:0)

不要使用您直接实现的_transform,_read,_write或_flush函数,这些函数用于节点的内部使用。

当您看到角色";"时发出自定义事件在你的流中:

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
});