我需要将通过线路表示数字的大字符串发送到用Java Script编写的客户端。从理论上讲,它是0s
和1s
的流,如:011101011101101...
,但它可能非常非常大(长度为数百万位)。当然,我的目标是尽量减少必要的处理和发送开销。我考虑过更改该字符串的基数,以便它使用HEX或更大的基数,这将大大减少必须发送的数据量。 JavaScript内置了用于转换到不同编号系统的函数,因此它看起来像是要走的路。但是,支持的最大基数只有36个。我的计算结果显示,当拥有50毫升的数据流并使用36个基数时,你仍然需要发送1,388,888
个字符 - 太多了。
我的问题是 - 你知道有什么方法可以帮助我实现目标吗?一些约束:
答案 0 :(得分:0)
你可以做这样的事情(这个演示已经编写过,无法测试它,但它“应该工作了”,这对于那些想要复制/剪切/粘贴的人来说是个小提琴:http://fiddle.jshell.net/sywz3aym/2/
请注意小提琴不能运行,我打算写一个响应者,但我现在不能害怕。
在javascript入口区域的底部,我有一个关于asp.net响应者可以看的评论部分,如果你使用visual studio,它使用“Generic Handler(.ashx)”文件,如果你使用任何其他语言你将不得不使用那里的等价选项。您需要一个可以自定义的请求响应器来返回二进制数据,您需要将Content-Type设置为“application / octet-stream”(对于那些不知道的人来说是八位字节=“8位组”,例如一个字节: ))
这里是javascript +评论,就像文字格式的辉煌一样:
$(document).ready(function () {
var url = 'your handler URL';
var oReq = new XMLHttpRequest();
oReq.open('GET', url, true);
oReq.responseType = 'arraybuffer';
oReq.onload = function (oEvent) {
var buffer = oReq.response;
var yourData = ExtractData(buffer);
}
oReq.send(null);
});
function ExtractData(buffer) {
var dataReader = {
dataView: new DataView(buffer),
readPtr: 0,
littleEndian: (function () {
var buffer = new ArrayBuffer(2);
new DataView(buffer).setInt16(0, 256, true);
return new Int16Array(buffer)[0] === 256;
})(),
setReadPtrOffset: function (byteIndex) {
this.readPtr = byteIndex;
},
nextInt8: function () {
var data = this.dataView.getInt8(this.readPtr);
this.readPtr += 1; // Sizeof int
return data;
},
nextUint8: function () {
var data = this.dataView.getUint8(this.readPtr);
this.readPtr += 1; // Sizeof int8
return data;
},
nextInt32: function () {
var data = this.dataView.getInt32(this.readPtr, this.littleEndian);
this.readPtr += 4; // Sizeof int32
return data;
},
nextUint32: function () {
var data = this.dataView.getUint32(this.readPtr, this.littleEndian);
this.readPtr += 4; // Sizeof uint32
return data;
},
nextFloat32: function () {
var data = this.dataView.getFloat32(this.readPtr, this.littleEndian);
this.readPtr += 4; // Sizeof float
return data;
},
nextFloat64: function () {
var data = this.dataView.getFloat64(this.readPtr, this.littleEndian);
this.readPtr += 8; // Sizeof double
return data;
},
nextUTF8String: function (length) {
var data = String.fromCharCode.apply(null, new Uint8Array(this.dataView.buffer, this.readPtr, length));
this.readPtr += length; // Sizeof int
return data;
},
}
var numberOfInt32ToRead = dataReader.nextInt32(); // First data could be, for example, the number of ints to read.
for(var i = 0; i < numberOfInt32ToRead; i++){
var someInt = dataReader.nextInt32();
// doStuffWithInt(someInt);
}
}
/*
Serverside code looks kind of like this (asp.net/c#):
public class YourVeryNiceDataRequestHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/octet-stream"; // <- very important
List<int> data = SomeMethodWithGivesYouData();
context.Response.BinaryWrite(BitConverter.GetBytes((int)data.Count)); // Explicit type casting only to help me get an overview of the data being sent, in this case it has no functional meaning other then to help me debug
foreach(int i in data)
{
context.Response.BinaryWrite(BitConverter.GetBytes((int)i));
}
// You could send structs as well, either with the help of a binary formatter, or you can do like i did here and use BitConverter.GetBytes, be carefull when sending strings/chars since they are by default (usually) in a widechar format (1 char = 2 bytes), since i only use english for this i can convert it to a UTF8 char (1 byte): context.Response.BinaryWrite(System.Text.Encoding.UTF8.GetBytes(new char[] { (motion.Phase == Phases.Concentric ? 'C' : 'E') })); // Phase (as single char)
}
}
*/
我希望这可以直接帮助您,或指导您正确的方向
请注意,这很大程度上取决于您的服务器使用的数据类型,并且可能不属于您的“REST”类别,但您确实表示您希望针对流大小进行优化,而此afaik是最佳方法除了添加数据压缩之外
Javascript类型数组“模仿”c样式数据类型,如c,c ++,c#,java等中使用的
<强> Disclamer:
我还没有尝试使用数据&gt;然而,它确实将从服务器发送到客户端的数据的总大小从2MB减少到几个10-100~KB,并且对于我发送/读取执行时间的数据量是“不可人为可测量的”其他然后是额外请求的往返时间,因为这是在浏览器中加载页面后请求的
最后的警告:任何手动位序列化/反序列化应该小心,因为很容易弄错,忘记你已经改变了客户端或服务器端的东西,它会让你联合国-debuggable垃圾,如果你在任何一端读取或写入太多/太少的字节,这就是为什么我在我的服务器端代码中添加显式类型转换,这样我可以打开服务器代码和客户端代码旁边-side并将readInt32与Write((int)...)匹配 这不是一个有趣的工作,但它使事情变得非常紧凑和非常快(通常我会考虑可读性,但有些任务只需要比可读代码更快地工作)。
然而,键入的数组不能在每个浏览器中使用,但可以说85%的互联网可以使用它们:http://caniuse.com/#feat=typedarrays