Node.js Readable Stream _read Utilisation

Je comprends comment utiliser des stream inscriptibles dans la nouvelle bibliothèque Streams2 Node, mais je ne comprends pas comment utiliser des stream lisibles.

Prenons, par exemple, un wrapper de stream autour du module dgram :

 var dgram = require('dgram'); var thumbs = { twiddle: function() {} }; var defaults = { address: '0.0.0.0', type: 'udp4', port: 12345, broadcast: null, multicast: null, multicastTTL: 1 }; var UDPStream = function(options) { if (!(this instanceof UDPStream)) return new UDPStream(options); Duplex.call(this); options = options || {}; this.address = options.address || defaults.address; this.type = options.type || defaults.type; this.port = options.port || defaults.port; this.broadcast = options.broadcast || defaults.broadcast; this.multicast = options.multicast || defaults.multicast; this.multicastTTL = options.multicastTTL || defaults.multicastTTL; this._socket = dgram.createSocket(this.type, setup.bind(this)); this._socket.on('message', this.push.bind(this)); }; util.inherits(UDPStream, Duplex); var setup = function() { if (this.multicast) { this._socket.addMembership(this.multicast); this._socket.setMulticastTTL(this.multicastTTL); this.destination = this.multicast; } else { // default to using broadcast if multicast address is not specified. this._socket.setBroadcast(true); // TODO: get the default broadcast address from os.networkInterfaces() (not currently returned) this.destination = this.broadcast || '255.255.255.255'; } }; UDPStream.prototype._read = function(size) { thumbs.twiddle(); }; UDPStream.prototype._write = function(chunk, encoding, callback) { this._socket.send(chunk, 0, chunk.length, this.port, this.destination); callback(); }; module.exports = UDPStream; 

Tout a un sens sauf pour l’implémentation _read . Il s’agit littéralement de tourner les pouces parce que je ne comprends pas ce que je suis censé faire ici. Mes données sont envoyées lorsque le socket udp émet un nouveau message, mais je n’ai aucun moyen de suspendre ou de reprendre la ressource sous-jacente. À quoi cela devrait- il ressembler?

_read fait partie du mécanisme de reprise de pause. À partir de la documentation de l’API NodeJS

Lorsque des données sont disponibles, placez-les dans la queue de lecture en appelant readable.push (chunk). Si push renvoie false, alors vous devriez arrêter de lire. Lorsque _read est appelé à nouveau, vous devriez commencer à envoyer plus de données.

Ainsi, dans votre fonction _write, si l’appel socket.send échoue en renvoyant false ou en appelant un rappel avec une erreur, vous devez mettre en pause votre stream. _read alors peut simplement faire this._paused = false

Pourrait ressembler à ceci.

 UDPStream.prototype._read = function() { this._paused = false; } UDPStream.prototype._write = function(chunk, encoding, callback) { if(!this._paused) this._socket.send(chunk, 0, chunk.length, this.port, this.destination); }; 

La réponse est assez simple: s’il n’ya vraiment aucun moyen d’appliquer une contre-pression à votre ressource sous-jacente, votre implémentation de _read est simplement vide. Le stream se chargera de mettre vos données highWaterMark attente jusqu’à ce qu’il highWaterMark , mais ne garantit rien au-delà de ce point. Les docs disent que vous devriez “simplement fournir des données dès qu’elles deviennent disponibles”.