试图通过Websocket将压缩的base64编码字符串从JS发送到AS3.解压缩问题



大家好,祝2021年更加快乐和健康!

我正在JS客户端和AS3服务器之间建立一个基于Websockets协议的小型通信接口。由于各种原因,我需要对有效载荷进行压缩和base64编码。从AS3到JS,一切都是这样工作的(使用https://github.com/blooddy/blooddy_crypto处理Base64 en/解密(:

function encodeMessage(message:String):String{
var rawData:ByteArray=new ByteArray()
rawData.writeUTFBytes( encodeURIComponent(message) );
rawData.compress();
var b64 = Base64.encode(rawData);
return b64;
};

用pako在JS中解码通货膨胀(https://github.com/nodeca/pako):

decodePayload(payload){
let rawfile = (atob(payload));
var bytes = [];
for (var fileidx = 0; fileidx < rawfile.length; fileidx++) {
var abyte = rawfile.charCodeAt(fileidx) & 0xff;
bytes.push(abyte);
}
var plain = pako.inflate(bytes);
var enc = "";
for (var i = 0; i < plain.length; i++) {         
enc += String.fromCharCode(plain[i]);
}
return decodeURIComponent(enc);
}

现在,另一个方向产生了一些问题:在JS中我使用:

encodeMessage(message){
let enc = encodeURIComponent(message)
let zlib = pako.deflate(enc)
let b64 = btoa(zlib);
return b64;
}

但后来我遇到了AS3方面的问题:

function decodePayload(payload:String){
var ba:ByteArray = Base64.decode(payload);
//this is where the error happens
ba.uncompress();

}

该错误是一个"错误";错误:错误#2058:解压缩数据时出错"我怀疑我从pako.delate收到的字节与AS3使用的字节不同?

欢迎任何指点!

这里是解决方案-当然是一个愚蠢的小疏忽;(

在JS中的encode函数中,Uint8Array需要转换为BinaryString,然后才能进行Base64编码:

function encodeMessage(message){
let enc = encodeURIComponent(message);
let zlib = pako.deflate(enc);
let binstring = convertUint8ArrayToBinaryString(zlib); 
let b64 = btoa(binstring);
return b64;
};
function convertUint8ArrayToBinaryString(u8Array) {

var i, len = u8Array.length, b_str = "";
for (i=0; i<len; i++) {
b_str += String.fromCharCode(u8Array[i]);
}
return b_str;
}

那么罗斯威尔一切都很好。

如果您的AS3代码只在SWF文件中使用,或者您有一个AIR项目,这并不明显。

  • 如果制作AIR项目:

尝试使用uncompress.apply。。。(代码尚未测试(。

//# this is where the error happens
//ba.uncompress();
//# try this..
ba.uncompress.apply(ba, ["deflate"]);
  • 如果制作SWF项目:

当我需要在浏览器上运行的SWF中使用Deflate算法时,我使用了Zlib端口。

获取as3zlib,网址:https://github.com/BenV/as3zlib(是用于Java的Zlib的端口(。

注意:虽然在JS中最好制作本地变量,而不是全局变量,但这是JavaScript的一个怪癖事实上,在大多数类C语言(Java、C#、AS3等(中,情况恰恰相反,全局变量比每次调用函数时不断地生成局部vars成本更低。

下面是一个用法示例:

//# import Zlib Class
import Zlib;
//# setup global vars
var zlibdecomp :Zlib;
var ba :ByteArray = new ByteArray;
var decoded_BA :ByteArray = new ByteArray;
//# try Deflate algo...
function decodePayload(payload:String)
{
zlibdecomp = new Zlib;
ba.clear(); //in case it already has data from a prev decode

//# all code below can be done in this one line
//ba = zlibdecomp.uncompress( Base64.decode(payload) );

ba = Base64.decode(payload);

//# this is where the error happens...
//ba.uncompress();

//# try this...
decoded_BA = zlibdecomp.uncompress( ba ); //inflate to original big from small/compressed
//ba = decoded_BA; //if this way of updating is needed
}

最新更新