2012-01-12 23 views
0

我必須發送大量數據給連接到我的服務器的小客戶端。寫入循環中的通道

所以,我有這樣的:

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

的問題是,由於某種原因,客戶端接收髒數據,像Netty的緩衝區不是在每次迭代清楚,所以我們得到了像「你好WorldHello」。

如果我讓我的代碼把一個線程睡眠一切變化不大正常工作:

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

回答

0

在兩種情況下,你發送任何指示,其中一個項目結束和下一個開始,或者每個多久項目是。

在第二種情況下,睡眠正在使通道超時並刷新,所以客戶端會看到一個'break',它將其解釋爲項目的結束。

+0

在這兩種情況下,我沒有使用任何禁用此以表明結束。 – user1146287 2012-01-13 13:02:48

+1

在這兩種情況下,客戶端都會根據需要讀取儘可能多的輸入,或者在創建項目時可用,然後循環查找下一個項目。如果客戶在閱讀第一個項目之前等待了一秒以上,那麼當它讀取它的輸入時,它會看到第一個和第二個項目的數據位於其輸入中,並且會認爲這是單個項目。 – MRAB 2012-01-13 20:51:07

0

客戶端不應該看到這個「髒數據」。如果真的如此,那麼它就是一個錯誤。但是,要想成爲可怕的人,我無法想象任何可能導致這種情況的東西。由於每個Channel.write(..)事件將被添加到隊列中,並在可能時寫入客戶端。因此,write(..)方法中傳遞的每個數據都將被寫入。沒有數據的「concat」。

您是否可能在將數據發送到客戶端之前緩衝數據的流水線中有一些自定義編碼器?

它還將幫助,如果你能證明的完整代碼,讓這個behavoir所以我們看到的處理程序是在管道等

+0

我不使用自定義編碼器,實際代碼是:\t \t(座標VO座標:座標){ \t \t \t sendToClient.add(coordinate); \t \t \t如果(sendToClient.size()== 2){ \t \t \t \t字符串resultSerialized =新GSON()。toJson(sendToClient,new TypeToken >(){} .getType()); \t \t \t \t logger.info(「Sending:」+ 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 2012-01-13 13:21:19

+0

你可以在「代碼標記」中插入你的「代碼」嗎?它真的很難閱讀.. – 2012-01-13 17:19:45

1

正如MRAB說,如果服務器在通道上發送多條消息沒有說明每條消息的結尾,則客戶端不能總是正確地讀取消息。通過在寫入消息之後添加睡眠時間,也不會解決問題的根本原因。

要解決這個問題,必須以其他方可識別的方式標記每個消息的結尾,如果客戶端和服務器都使用Netty,則可以在json處理程序之前添加LengthFieldPrepender和LengthFieldBasedFrameDecoder。

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 2012-01-16 11:57:28