hasmet
hasmet

Reputation: 778

Pass Binary Data with WebSocket

I'm writing a Firefox extension and I'm searching to pass a zipped file with a WebSocket (server here). The code is the following for the client side (that send the file):

var ws = new window.WebSocket("ws://localhost:12345");

function sendLogToOtherClient(file){

   var zippedFileToSend = zipLogFile(file);
   NetUtil.asyncFetch(zippedFileToSend, function(inputStream, status) {
      if (!components.isSuccessCode(status)) {
         return;
   }
   var bstream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
   bstream.setInputStream(inputStream);
   var bytes = bstream.readByteArray(bstream.available());
   bstream.close();
   var encodedData = base64.encode(bytes, "utf-8");
   ws.send(encodedData);
   });
}
function zipLogFile(fileToZip){
   var zippedFile = FileUtils.getFile("ProfD", ["report1.zip"], false);
   var zipWriter = CCIN("@mozilla.org/zipwriter;1", "nsIZipWriter");
   zipWriter.open(zippedFile, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE);
   zipWriter.addEntryFile("logfile.txt", zipWriter.COMPRESSION_BEST, fileToZip, false);
   zipWriter.close();
   return zippedFile;
}

And this for Server side (that receive file and write new zipped file):

server = new WebSocketServer(12345);
server.onclient = function(client) {
   console.log(client + " connected");

   client.onmessage = function(client, msg) {
      client.send("Log Received");
      var zippedTmpFile = FileUtils.getFile("ProfD", ["report2.zip"], false);
      asyncTmpSave(zippedTmpFile, msg, onDone)

   };
};
server.connect();

function asyncTmpSave(file, data, callbackDone){
   var ostream = FileUtils.openFileOutputStream(file, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE);
   var converter = CCIN('@mozilla.org/intl/scriptableunicodeconverter', "nsIScriptableUnicodeConverter");
   converter.charset = 'UTF-8';
   var istream = converter.convertToInputStream(data);

   NetUtil.asyncCopy(istream, ostream, callbackSaved); 
      function callbackSaved (status) {     
         if(callbackDone){
           if(status===0)callbackDone( file.path, file.leafName, status);  //sucess.
           else callbackDone( null, null, status); //failure.
      }; 
  }
}
function onDone(path, leafName, statusCode){
   console.log([statusCode===0?"OK":"error",path,leafName].join("\n"));
}

I've tryed to pass string and the communication works, and in this case data are passed and the file is created, but the .zip file is corrupted. Do you have any ideas? Thanks

Upvotes: 0

Views: 2781

Answers (1)

nmaier
nmaier

Reputation: 33192

You cannot utf-8 encode random, binary stuff.

WebSockets (and my server) support typed arrays.

So you'll when sending want:

var bytes = new Uint8Array(bstream.available());
bstream.readArrayBuffer(bytes.byteLength, bytes.buffer);
bstream.close();
ws.send(bytes);

And on the receiving end you'll receive an Uint8Array as well.

Upvotes: 2

Related Questions