Netty4客户端使用遇到的坑笔记

1.注意ChannelPipeline中handler的调用顺序。完整的发送与接收过程,是先发送再接收,所以是先执行out再执行in。具体参考https://blog.csdn.net/u014614038/article/details/80487942

2.发送数据转码,通过MessageToByteEncoder,比如我使用的是SMessage格式数据:

public class SDataEncoder extends MessageToByteEncoder<SMessage> {

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, SMessage sMessage, ByteBuf byteBuf) throws Exception {
        if (sMessage != null) {
            ByteBuf encoded = channelHandlerContext.alloc().buffer(sMessage.getByteData().length);
            encoded.writeBytes(sMessage.getByteData());
            channelHandlerContext.writeAndFlush(encoded);
            channelHandlerContext.flush();
        }
    }

}

3.接收数据转码,通过ByteToMessageDecoder,比如将字节数据转为我使用的SMessage:

public class SDataDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        try {
            ByteBuf d = in.readBytes(in.readableBytes());
            byte[] bs = new byte[d.readableBytes()];
            d.readBytes(bs);
            if (bs.length>0) {
                SMessage sMessage = new SMessage();
                sMessage.data = bs;
                //获取header
                if (sMessage.hasData() && sMessage.data.length >= SHeader.LENGTH) {
                    byte[] headBs = new byte[SHeader.LENGTH];
                    System.arraycopy(sMessage.data, 0, headBs, 0, headBs.length);
                    sMessage.header = new SHeader();
                    sMessage.header.setData(headBs);
                }

                //获取数据body
                if (sMessage.hasData() && sMessage.data.length > SHeader.LENGTH) {
                    byte[] bodyBs = new byte[sMessage.data.length - SHeader.LENGTH];
                    System.arraycopy(sMessage.data, SHeader.LENGTH, bodyBs, 0, bodyBs.length);
                    sMessage.body = new SBody();
                    sMessage.body.dataByte = bodyBs;
                }           
                out.add(sMessage);
            } else {
                   out.add(d);
            }
        } catch (Exception e) {
            System.out.println("SDataDecoder decode Exception:" + e.toString());
        }
    }
}

这里记得注意的是,不能直接使用ByteBuf,否则会报Exception:java.lang.UnsupportedOperationException: direct buffer异常,需要通过 in.readBytes(in.readableBytes())复制一个新的ByteBuf然后读取字节数据。

4.发送过程抛出异常,包括自己代码写的不好导致的,最终会回调到ClientDataHandler的channelInactive,如果在这个方法执行了重连,可能会导致不断重连,建议捕捉下,避免代码导致的不断重连(比如心跳发送抛出异常,而你会不断发送心跳包)。

转载注明:https://blog.csdn.net/u014614038/article/details/80497785

相关文章
相关标签/搜索