สตรีมใน NodeJS

ฉันต้องการความช่วยเหลือเพื่อทำความเข้าใจวิธีการทำงานของสตรีมใน NodeJS

ฉันอธิบายว่าฉันต้องเขียนโมดูลที่เรียกกระบวนการ UNIX (ด้วย spawn) และฉันต้องการเปลี่ยนเส้นทาง stdout ของกระบวนการนี้ไปยังสตรีมที่อ่านได้

ฉันต้องการให้พฤติกรรมนี้ exports สตรีมที่อ่านได้ และอนุญาตให้โมดูลอื่นอ่านได้

เพื่อที่จะทำสิ่งนี้ ฉันได้เขียนโค้ดเล็กๆ น้อยๆ :

var spawn = require('child_process').spawn
var Duplex = require('stream').Duplex;
var stream = new Duplex;


var start = function() {
    ps = spawn('mycmd', [/*... args ...*/]);
    ps.stdout.pipe(stream);
};


exports.stream = stream;
exports.start = start;

แต่ถ้าฉันใช้โมดูลนี้ ฉันจะส่งข้อยกเว้นที่บอกว่าสตรีมไม่ได้ใช้เมธอด _read

คุณช่วยฉันแก้ปัญหานี้ได้ไหม?

ขอบคุณล่วงหน้า.

[แก้ไข] ฉันได้ลองใช้วิธีแก้ปัญหาในการสร้างวัตถุ Stream แล้ว แต่ไม่ได้ผล นี่คือโค้ด:

var spawn = require('child_process').spawn;
var Stream = require('stream');
var ps = null;

var audio = new Stream;
audio.readable = audio.writable = true;

var start = function() {
    if(ps == null) {
        ps = spawn('mycmd', []);

        ps.stdout.pipe(stream);
    }
};

var stop = function() {
    if(ps) {
        ps.kill();
        ps = null;
    }
};


exports.stream = stream;
exports.start = start;
exports.stop = stop;

แต่เมื่อฉันพยายามฟังสตรีม ฉันพบข้อผิดพลาดใหม่:

_stream_readable.js:583
    var written = dest.write(chunk);
                       ^
TypeError: Object #<Stream> has no method 'write'

person Vincent Saluzzo    schedule 27.08.2013    source แหล่งที่มา
comment
คุณต้องการใช้ stream หรือต้องการใช้ stream หรือไม่?   -  person user568109    schedule 27.08.2013
comment
ฉันต้องการกำหนดสตรีมที่อ่านได้สำหรับผู้ใช้ที่ใช้โมดูลของฉัน และฉันต้องการเติมสตรีมนี้ด้วยข้อมูลที่จัดทำโดย stdout ของกระบวนการที่สร้างของฉัน   -  person Vincent Saluzzo    schedule 27.08.2013


คำตอบ (2)


คลาสสตรีมของโหนดส่วนใหญ่ไม่ได้มีไว้สำหรับใช้โดยตรง แต่เป็นฐาน ประเภทที่กำหนดเอง:

โปรดทราบว่า stream.Duplex เป็นคลาสนามธรรมที่ออกแบบมาเพื่อขยายด้วยการใช้งานพื้นฐานของเมธอด _read(size) และ _write(chunk, encoding, callback) เช่นเดียวกับที่คุณใช้กับคลาสสตรีมแบบอ่านได้หรือแบบเขียนได้

ข้อยกเว้นที่น่าสังเกตประการหนึ่งคือ stream.PassThrough ซึ่งเป็นการใช้งานสตรีมเสียงสะท้อนแบบง่ายๆ

var PassThrough = require('stream').PassThrough;
var stream = new PassThrough;

โปรดทราบว่า ps จะเป็นแบบโกลบอล ทำให้สามารถเข้าถึงได้โดยตรงในโมดูลอื่นๆ ทั้งหมด

person Jonathan Lonowski    schedule 27.08.2013
comment
ยอดเยี่ยม ! นั่นไปงาน! - person Vincent Saluzzo; 28.08.2013

หากคุณต้องการใช้ stream คุณควรทำ:

var stream = new Stream;
stream.readable = stream.writable = true;

Duplex มีไว้สำหรับนักพัฒนา จำเป็นต้องใช้วิธีการบางอย่างเช่น _read และ _write

[อัปเดต]

โอเค คุณมีแหล่งข้อมูลจาก stdout คุณจะต้องมีฟังก์ชัน write ใช้สิ่งนี้:

stream.write = function(data){this.emit('data', data);};
person user568109    schedule 27.08.2013
comment
โอเค ฉันทำให้แม่บ้านสับสนใช่ไหม? ฉันพยายามใช้ Stream เป็นผู้ให้บริการสตรีม แต่ในความเป็นจริง แม้ว่าฉันจะส่งข้อมูลไปที่ Stream แต่พฤติกรรมที่ฉันต้องการนั้นไม่ได้มีไว้สำหรับผู้ให้บริการ Stream ใช่ไหม - person Vincent Saluzzo; 27.08.2013
comment
ในฐานะผู้ให้บริการ Stream คุณจะใช้ ReadableStream เพื่ออ่านจากแหล่งอ้างอิงเช่น ไฟล์บนดิสก์ คุณจะต้องใช้การเปิดไฟล์ การอ่าน การพุช ฯลฯ ฉันคิดว่าสิ่งที่คุณต้องการคือสตรีมในไลบรารีของคุณ เพื่อให้ผู้อื่นสามารถอ่านจากมันได้ หากคุณต้องการให้เป็นไปป์คุณไม่จำเป็นต้องใช้สตรีม - person user568109; 27.08.2013
comment
ตกลง ฉันได้ลองวิธีแก้ปัญหาของคุณแล้ว แต่เมื่อฉันพยายามอ่านจากสตรีม ฉันโยนข้อยกเว้น : _stream_readable.js:583 var wrote = dest.write(chunk); ^ TypeError: Object #‹Stream› ไม่มีวิธี 'write' - person Vincent Saluzzo; 28.08.2013