2012-01-12 1 views
0

Мне нужно отправить много данных на I-клиент, подключенный к моему серверу небольшими блоками.Запись на канал в цикле

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

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

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

Если бы я сделать небольшое изменение в моем коде положить нить спать все работает отлично:

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

ответ

0

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

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

+0

В обеих случаях я ничего не использовать для обозначения конца. – user1146287

+1

В обоих случаях клиент считывает столько вкладов, сколько им нужно или доступно на момент создания элемента, а затем цикл для следующего элемента. Если клиент ждал более секунды, прежде чем читать первый элемент, тогда, когда он прочитает его ввод, он увидит данные как для первого, так и для второго элемента, сидящего на своем входе, и подумает, что это единственный элемент. – MRAB

0

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

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

Это также поможет, если вы могли бы показать полный код, который дает этот behavoir поэтому мы видим, что обработчики в трубопроводе и т.д.

+0

Я не использую пользовательский кодировщик, реальный код: \t \t для (CoordinateVO координат: координаты) { \t \t \t sendToClient.add (координаты); \t \t \t, если (== sendToClient.size() 2) { \t \t \t \t Строка resultSerialized = новый Gson().toJson (sendToClient, новый TypeToken >() {} .getType()); \t \t \t \t logger.info ("Отправка:" + resultSerialized); \t \t \t \t ChannelBuffer channelBuffer = ChannelBuffers.buffer (resultSerialized.getBytes(). Length); \t \t \t \t channelBuffer.writeBytes (resultSerialized.getBytes()); \t \t \t \t e.getChannel(). Write (channelBuffer); \t \t \t \t \t \t \t \t \t \t \t \t sendToClient.clear(); \t \t \t} \t \t} – user1146287

+0

Могли бы вы вставить «код» в «код разметки»? Его действительно трудно читать .. –

1

Как сказал 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

Как я могу добавить параметры LengthFieldPrepender и LengthFieldBasedFrameDecode? Еще раз спасибо! – user1146287

 Смежные вопросы

  • Нет связанных вопросов^_^