Вы могли бы сделать что-то вроде этого (демо было написано без возможности его тестирования, но оно должно «работать», вот скрипка для тех, кто хочет скопировать/вырезать/вставить: http://fiddle.jshell.net/sywz3aym/2/
Обратите внимание на скрипку не могу работать, я намеревался написать ответчика, но я не могу сейчас бояться.
В нижней части области ввода javascript У меня есть раздел комментариев о том, как может выглядеть ответчик asp.net, он использует файл «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)
}
}
*/
Я надеюсь, что это либо поможет вам непосредственно, либо направить вас в правильном направлении.
Обратите внимание: это ОЧЕНЬ зависит от ваших типов данных, которые используют ваш сервер, и может не попасть в категорию «ОТДЫХ», однако вы указали, что хотите оптимизировать размер потока, и этот афайк - лучший способ сделать что, за исключением добавления сжатия данных
Javascript типизированных массивы "подражает" тип данные C-стиль, как те, которые используются в C, C++, C#, Java и т.д.
Юридической информация:
у меня есть не пробовал это с данными> 1 МБ, однако он сократил общий размер данных, отправляемых с сервера на клиента с 2 МБ до нескольких 10-100 КБ, и i т на сумму данных я отправить/чтение время выполнения были «не по-человечески измеримое» другой, то туда и обратно время для дополнительного запроса, так как это испрашивается ПОСЛЕ загрузки страницы в браузере
заключительное слово предупреждение: любая ручная сериализация/десериализация битов вручную должна выполняться с осторожностью, так как очень легко сделать ошибку, забыв, что вы что-то изменили как на стороне клиента, так и на стороне сервера, и это даст вам отлаживаемый мусор, если вы читаете или пишете байта слишком много/слишком мало на обоих концах, поэтому я добавляю явное наследование типов в своем серверном коде, таким образом я могу открыть как код сервера, так и код клиента бок о бок и сопоставить readInt32 с Write ((целое) ...).
Не забавная работа, но она делает вещи очень компактными и очень быстрыми (как правило, я буду читать, но некоторые задачи должны работать быстрее, чем читаемый код).
типизированные массивы не могут быть использованы в любом браузере, однако, но caniuse состояние, что 85% Интернета может использовать их: http://caniuse.com/#feat=typedarrays
я что-то вроде этого какое-то время назад, я использовал типизированные массивы (без устаревших поддержка браузера) и jquery. Какой серверный язык вы используете? Я мог бы опубликовать либо клиентский скрипт, либо оба примера клиента + сервера. И это не ракетостроение, я не уверен, что это супер правильный способ сделать это, но он отлично поработал для нас. Это отправит данные в двоичном формате, например. вам не нужно кодировать/декодировать номера в/из строк – Snellface
Вы думали о том, чтобы ввести какое-то простое сжатие? Например, вместо отправки 111100000 вы можете отправить 1405, где число после 0/1 представляет количество вхождений. –
@MiljenMikic Я попробовал сжатие LZ77 на двоичных строках, но он только уменьшил поток 64k до примерно 36k. Это даже не половина :( –