0

I found an example of creating an event Emitter class that takes a stream (tcp net connection) and emits it's own custom events from the data events it pulls off of that stream.

No matter what I do I can't remake it will es6 class syntax. I saw in the node docs that this should be possible. But I have a weak OOP background and I just can't get the thing to work.

I'm sure someone could easily figure it out tho. Here is the original class (es5 style constructor / util module for extending...)

const MsgClient = function(stream) {
  events.EventEmitter.call(this);  

  let self = this, buffer = "";

  stream.on("data", (data) => {
    buffer += data;
    let boundary = buffer.indexOf("\n");
    while (boundary !== -1) {
      let input = buffer.substr(0, boundary);
      self.emit("message", JSON.parse(input));
      buffer = buffer.substr(boundary + 1);
      boundary = buffer.indexOf("\n");
    }
  })
}

util.inherits(MsgClient, EventEmitter); // from require("events").EventEmitter

In my naivety I've tried the following, but I just don't have the background to not get lost when it doesn't work. "This" gets really convoluted if you're not used to it...

class MsgClient extends EventEmitter {
  constructor(stream) {
    super();
    this.stream = stream;
    this.buffer = "";
    self = this;
  }

  stream.on("data", (data) => {
    buffer += data;
    let boundary = buffer.indexOf("\n");

    while (boundary !== -1) {
      let input = buffer.substr(0, boundary);
      self.emit("message", JSON.parse(input));
      buffer = buffer.substr(boundary + 1);
      boundary = buffer.indexOf("\n");
    }
  }) 
};

If anyone could help or even point me in the write direction it would be much appreciated.

MFave
  • 1,044
  • 2
  • 8
  • 19

3 Answers3

2

Try this:

class MsgClient extends EventEmitter {
  constructor(stream) {
    super();
    this.stream = stream;
    this.buffer = "";

    stream.on("data", (data) => {
      buffer += data;
      let boundary = buffer.indexOf("\n");

      while (boundary !== -1) {
        let input = buffer.substr(0, boundary);
        this.emit("message", JSON.parse(input));
        buffer = buffer.substr(boundary + 1);
        boundary = buffer.indexOf("\n");
      }
    })
  }
};
lilezek
  • 6,976
  • 1
  • 27
  • 45
0

Or try this, previous answer also should works but probably you wanted to do it in this way.

class MsgClient extends EventEmitter {
  constructor(stream) {
    super();
    this.stream = stream;
    this.buffer = "";
    this.onData = this.onData.bind(this);
    stream.on("data", this.onData);
  }

  onData(data){
    buffer += data;
    let boundary = buffer.indexOf("\n");

    while (boundary !== -1) {
      let input = buffer.substr(0, boundary);
      this.emit("message", JSON.parse(input));
      buffer = buffer.substr(boundary + 1);
      boundary = buffer.indexOf("\n");
    }
  }
}

EDIT: It should now to compile and work

M. Galczynski
  • 634
  • 1
  • 5
  • 12
  • 1
    Why `he probably wants` to do that way? This does not even compile. – lilezek Oct 17 '17 at 14:37
  • @lilezek yes, I made syntax error. And I suppose that because OP wanted to use ES 6 syntax and mentioned about Object Oriented Programing – M. Galczynski Oct 17 '17 at 14:47
  • Yes, but why he wants to have an additional function, which is only being used in the constructor and having the memory usage increased by having it bounded to `this`? – lilezek Oct 17 '17 at 14:48
  • I think that because OP tried to bind ondata listener outside constructor. Of course I can be also wrong and OP wants to save memory – M. Galczynski Oct 17 '17 at 14:59
0

This ended up working just fine:

class MsgClient extends EventEmitter {
  constructor(stream) {
    super();
    let buffer = "";

    stream.on("data", (data) => {
      buffer += data;
      let boundary = buffer.indexOf("\n");

      while (boundary !== -1) {
        let input = buffer.substr(0, boundary);
        this.emit("message", JSON.parse(input));
        buffer = buffer.substr(boundary + 1);
        boundary = buffer.indexOf("\n");
      }
    });
  }
};

The thing I was missing was that the entire "stream.on" method was being declared right in the constructor, so thanks for pointing that out. This code now works as the original es5 type class did.

MFave
  • 1,044
  • 2
  • 8
  • 19