Запись на канал в цикле - PullRequest
0 голосов
/ 12 января 2012

Я должен отправить много данных клиенту, подключенному к моему серверу небольшими блоками.

Итак, у меня есть что-то вроде:

for(;;) { 
    messageEvent.getChannel().write("Hello World");
}

Проблема в том, что дляпо какой-то причине клиент получает грязные данные, например, буфер Netty не очищается на каждой итерации, поэтому мы получаем что-то вроде «Hello WorldHello».

Если я внесу небольшое изменение в свой код, поместив нить в спящий режим, все работаетштраф:

for(;;) { 
    messageEvent.getChannel().write("Hello World");
    Thread.sleep(1000);
}

Ответы [ 3 ]

1 голос
/ 14 января 2012

Как сказал MRAB, если сервер отправляет несколько сообщений по каналу без указания конца каждого сообщения, клиент не всегда может правильно прочитать сообщения. Добавление времени ожидания после написания сообщения также не устранит причину проблемы.

Чтобы решить эту проблему, необходимо пометить конец каждого сообщения так, чтобы другая сторона могла его идентифицировать. Если клиент и сервер используют Netty, вы можете добавить LengthFieldPrepender и LengthFieldBasedFrameDecoder перед обработчиками json.

String encodedMsg = new  Gson().toJson(
sendToClient,newTypeToken<ArrayList<CoordinateVO>>() {}.getType());

По умолчанию Gson использует html-экранирование для содержимого, иногда это приводит к проводному кодированию, вы можете отключить его, если требуется, с помощью фабрики Gson

final static GsonBuilder gsonBuilder = new GsonBuilder().disableHtmlEscaping();

....

String encodedMsg = gsonBuilder.create().toJson(object);
0 голосов
/ 13 января 2012

Клиент никогда не должен видеть эти "грязные данные".Если это действительно так, то это ошибка.Но, чтобы быть искренним, я не могу думать ни о чем, что могло бы привести к этому в нетто.Поскольку каждое событие Channel.write (..) будет добавлено в очередь, которая затем будет по возможности записана клиенту.Таким образом, все данные, которые передаются в методе write (..), будут просто записаны.«Конкат» данных не существует.

Возможно, в конвейере есть какой-нибудь пользовательский кодировщик, который буферизует данные перед отправкой их клиенту?покажите полный код, который дает это поведение, чтобы мы увидели, какие обработчики находятся в конвейере и т. д.

0 голосов
/ 12 января 2012

Ни в том, ни в другом случае вы не отправляете что-либо, чтобы указать, где заканчивается один элемент и начинается следующий, или сколько длится каждый элемент.

Во втором случае сон отключает тайм-аут канала и сбрасывает его, поэтомуклиент видит «разрыв», который он интерпретирует как конец элемента.

...