解决netty客户端接收报文不完整的情况
逻辑就是在处理handler前加入一个处理符,然后
channelReadComplete这个事件进行处理。
同时注意客服端的配置:
1 public void connect(String addr, int port, final String xml, final String key,final boolean flag) throws Exception { 2 EventLoopGroup group = new NioEventLoopGroup(); 3 try { 4 Bootstrap b = new Bootstrap(); 5 b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true) 6 .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024*1024))//这行配置比较重要 7 .handler(new ChannelInitializer<SocketChannel>() { 8 protected void initChannel(SocketChannel ch) throws Exception { 9 ChannelPipeline pipeline = ch.pipeline(); 10 pipeline.addLast(new EsbClientHandler(xml, key,flag)); 11 } 12 }); 13 ChannelFuture f = b.connect(addr, port); 14 // 等待客户端关闭连接 15 f.channel().closeFuture().sync(); 16 } catch (Exception e) { 17 e.printStackTrace(); 18 } finally { 19 group.shutdownGracefully(); 20 } 21 }
源码如下:
1 public class EsbClientHandler extends ChannelHandlerAdapter { 2 3 private static Logger logger = Logger.getLogger(EsbClientHandler.class); 4 5 private ByteBuf byteMsg; 6 7 private boolean flag; 8 9 /** 10 * 临时客户端数据key 11 */ 12 private String key = "key"; 13 14 public EsbClientHandler(String xml, String key, boolean flag) { 15 this.key = key; 16 this.flag = flag; 17 byte[] req = null; 18 try { 19 req = xml.getBytes("UTF-8"); 20 } catch (UnsupportedEncodingException e) { 21 e.printStackTrace(); 22 } 23 byteMsg = Unpooled.buffer(req.length); 24 byteMsg.writeBytes(req); 25 } 26 27 @Override 28 public void channelActive(ChannelHandlerContext ctx) throws Exception { 29 ctx.writeAndFlush(byteMsg); 30 } 31 32 @Override 33 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 34 try { 35 ByteBuf buf = (ByteBuf) msg; 36 byte[] req = new byte[buf.readableBytes()]; 37 buf.readBytes(req); 38 String body = new String(req, "UTF-8"); 39 flag = true; 40 String xml = WebUtil.getXmlStr(body); 41 analysisXml(xml); 42 } catch (Exception e) { 43 e.printStackTrace(); 44 } finally { 45 ReferenceCountUtil.release(msg); 46 } 47 48 } 49 50 @Override 51 public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { 52 ctx.flush(); 53 if (flag) { 54 ctx.close(); 55 } else { 56 ctx.read(); 57 } 58 } 59 60 @Override 61 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 62 // 释放资源 63 ctx.close(); 64 } 65 66 /** 67 * 68 * 客户端解析服务端返回的xml数据,进行数据操作 69 * 70 * @param xml 71 */ 72 public void analysisXml(String xml) { 73 System.out.println("获取服务器接收报文:" + xml); 74 logger.info("开始解析xml:"); 75 logger.info(xml); 76 NettyMap.setDataMap(key, xml); 77 } 78 }