一、前情提要
果然話不能說太滿~~ 神馬完美解決~~ 果然還是遇到問題了。單純加in.skipBytes(in.readableBytes());這一句代碼會造成數據傳遞過去的都是一個EmptyByteBufBE ... ...
- 解碼斷點是有數據接收到的可讀長度416個字節
- 到handler裏的channelRead0中看到readerIndex已然是416,因爲是在解碼的時候是直接把與原本的ByteBuf傳遞到handler裏,但是在解碼的最後邏輯裏我又讀取了,跳過讀取其實就是讀取,只是一次性移動完readerIndex座標指向,也能看出來skipBytes這我寫在前面和後面都無區別,在數據流向handler的時候,都是最終被讀完的。
- 這樣就導致服務端收到的報文信息都是空的
- 前情代碼
@Override protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception { if(in.readableBytes() <= 0){ log.info("***********當前無數據報文,無需解碼***********"); return; } SocketData data = new SocketData(in); data.setpId(this.pId); ChannelData channelData = new ChannelData(data); ReferenceCountUtil.retain(in); out.add(channelData); in.skipBytes(in.readableBytes()); }
二、解決方案
- copy一份ByteBuf,把原本的這份讀取掉(或者說跳過讀取),然後傳遞副本。
代碼
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
if(in.readableBytes() <= 0){
log.info("***********當前無數據報文,無需解碼***********");
return;
}
ByteBuf dup = in.retainedDuplicate();
SocketData data = new SocketData(dup);
data.setpId(this.pId);
ChannelData channelData = new ChannelData(data);
ReferenceCountUtil.retain(in);
out.add(channelData);
in.skipBytes(in.readableBytes());
}
- 解碼器
- handler 裏 byteBuf的readerIndex已經是0開始了,因爲這是副本傳回來的,沒有經過讀取。
- 到服務端就有數據了