Transferer des données encodées en ZLIB via Socket.IO entre PHP et NodeJS

Je suis en train de réaliser une plateforme d'impression dans le cloud pour ma boite. Pour éviter de saturer la bande passante j'ai pris l'initiative de compresser les flux d'impressions avec la librairie ZLIB qui est prévue pour le cross-platform.

Quand on l'utilise via les sockets entre PHP et NodeJS ce n'est pas une partie de plaisir si on passe à coté d'un petit truc bien vicieux :

Coté PHP :

il faut encoder en base64 le flux compressé, ce qui donne :

$printData = file_get_contents(__DIR__."/monfichier.prn");
$printData = zlib_encode($printData, ZLIB_ENCODING_DEFLATE);
$printData = base64_encode($printData);

$printData peut ensuite être envoyé via un WebSocket Elephant.IO.

Apparté : Si vous souhaitez utiliser des certificats cryptés pour vos tests de dev avec Elephant.IO, ça ne marche plus dans la version 1.X. J'ai fait une pull-request à Wissembly pour améliorer ça.

Coté NodeJS :

Il faut "require" la librairie zlib (intégrée à Node). Le truc c'est de parser 2 fois la chaine reçue sur le WebSocket. Une fois en binaire et une autre fois en base64. Ensuite seulement on peut la décompresser. Si vous ne passez pas par la phase "binary" vous aurez une magnifique erreur du style "zlib inflate incorrect header check"

var zLib = require('zlib');
var dataZip = new Buffer(new Buffer(dataZip64, 'binary').toString(), 'base64');
zLib.inflate(dataZip, function(err, result) {
  if (err) {
    log.error('Inflate Error :');
    log.error(err);
  } 
  else {
    // Chaine décompressée !
    log.info(result); 
  }
});

J'ai passé une journée là-dessus. Rien sur Stackoverflow ou dans les docs de PHP ou de Node... 

Du coup, j'imagine que ça peut aider !

Commentaires

Posts les plus consultés de ce blog

Vidange - Laguna III Coupé 2.0 DCI 150

RFID RC522 on Raspberry PI with NodeJS