我使用的是nodejs 0.10和ws(websocket lib)。
我想实现自己的stream.Writable
类来发送websocket消息
我的约束是:
例如,如果我打电话:
myStream = new FoobarStream;
myStream.write(<a buffer of 7KB>);
myStream.end(<another buffer of 7KB>);
然后,我希望我的流能够在两条消息中发送这些数据:第一个将有其JSON标头,后跟10KB数据,第二个将有其JSON标头(包含&#34; last:true&#34;字段)后跟4KB数据。
这意味着我必须对数据发送进行临时调整,这意味着我必须找到一种方法来了解我何时编写消息的最后数据,因为这样&#34; last:true&#34;字段我必须写入JSON标题。
我不知道如何只继承stream.Writable的_write()
方法。似乎我无法在_write()中知道是否已调用end(),因此我无法使用&#34; last: true
&#34;来标记我的JSON标题。
这是否意味着我必须继承stream.Writable的end()
方法?
有什么想法吗?
答案 0 :(得分:0)
可以从那里定义自己的end
方法和句柄。但这意味着要重写原始end
方法中的一些代码。
相反,您可以保留内部缓冲区并处理prefinish
或finish
事件中的最后一块。这是一个简单的例子:
function FoobarStream(options){
Writable.call(this, options);
this.on('prefinish', function(){
if(this._buffer){
//process the last chunk
process.stdout.write('footer: '+ this._buffer+ "\n");
}
});
}
FoobarStream.prototype._write = function(chunk, encoding, cb){
if(this._buffer){
//process other chunks here
process.stdout.write('header: ' + this._buffer+ "\n");
this._buffer = chunk;
}
else
this._buffer = chunk;
cb();
}
myStream = new FoobarStream;
myStream.write('first line');
myStream.write('second line');
myStream.end('last line');
/*
outputs:
header: first line
header: second line
footer: last fine
*/
答案 1 :(得分:0)
您可以延迟写入接收器(基础WritableStream资源)直到process.nextTick
,这将允许您检查finish
(0.10中没有prefinish
)事件是否已在写入结果之前在流上触发。以下是您可以运行的示例:
var Stream = require('stream');
var Util = require('util');
// Create a readable to test our FoobarStream out
var readable = new Stream.Readable();
var finished = false;
readable._read = function () {
if (finished) {
this.push(new Buffer('world'));
return this.push(null);
}
this.push(new Buffer('hello '));
finished = true;
};
// Create the FoobarStream
var FoobarStream = function (options, sink) {
Stream.Writable.call(this, options);
this.sink = sink;
this.finished = false;
this.on('finish', function () {
this.finished = true;
});
};
Util.inherits(FoobarStream, Stream.Writable);
FoobarStream.prototype.serialize = function (chunk) {
var header = new Buffer(JSON.stringify({some: 'header', last: this.finished}));
return Buffer.concat([header, chunk]);
};
FoobarStream.prototype._write = function (chunk, encoding, callback) {
var self = this;
process.nextTick(function () {
self.sink.write(self.serialize(chunk));
});
callback();
}
readable.pipe(new FoobarStream(null, process.stdout));
控制台输出:
$ node index.js
{"my":"header","last":false}hello
{"my":"header","last":true}world