netty custom protocol

netty custom protocol

Netty What is it?

I believe many people have been asked this question. If fast and accurate responses to this problem? Network programming framework, netty allows you to quickly and simply develop a high-performance network applications. netty network programming is a framework. That netty what frame it? There are two boxes.

Start and customer service: Box 1

All communications are sent and received, all the services and client are like posture starts. Specific parameters can look at the document.

Server

 public void bind() throws Exception {
        // 配置服务端的NIO线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        ServerBootstrap b = new ServerBootstrap();

        
        //需要两个线程组
        b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
            .option(ChannelOption.SO_BACKLOG, 1024)
            .childHandler(new ServerInit());

        // 绑定端口,同步等待成功
        b.bind(NettyConstant.REMOTE_PORT).sync();
            LOG.info("Netty server start : "
                + (NettyConstant.REMOTE_IP + " : " + NettyConstant.REMOTE_PORT));
    }

Client

          Bootstrap b = new Bootstrap();
            b.group(group).channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ClientInit());
            // 发起异步连接操作
            ChannelFuture future = b.connect(
                    new InetSocketAddress(host, port)).sync();
            channel = future.sync().channel();
            
            future.channel().closeFuture().sync();

Box 2: a processor ChannelHandler

netty all received or sent out to the data processor, hannelInboundHandler inbound processor, ChannelOutboundHandler outbound processor. Inbound data is received both trigger is triggered when the outbound transmission. The two interfaces also comprises an encoder and decoder, respectively implementations. So we have to extend the functionality to the server or the client, then! As long as the corresponding creation of a class to implement these two interfaces to add the channel on the line. netty as a framework, of course, help us to achieve many of the frequently used processor, such as: StringDecoder (String decoder), StringEncoder (string encoder), LengthFieldPrepender (added to the data packet length of half a pack sticky to resolve the problem ), ReadTimeoutHandler (timeout)

Add access server station processor


**
 * @author hdk
 * 类说明:服务端入站处理器初始化类
 */
public class ServerInit extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        /*Netty提供的日志打印Handler,可以展示发送接收出去的字节*/
        //ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
        /*剥离接收到的消息的长度字段,拿到实际的消息报文的字节数组*/
        ch.pipeline().addLast("frameDecoder",
                new LengthFieldBasedFrameDecoder(65535,
                        0,2,0,
                        2));
        /*给发送出去的消息增加长度字段*/
        ch.pipeline().addLast("frameEncoder",
                new LengthFieldPrepender(2));
        /*反序列化,将字节数组转换为消息实体*/
        ch.pipeline().addLast(new KryoDecoder());
        /*序列化,将消息实体转换为字节数组准备进行网络传输*/
        ch.pipeline().addLast("MessageEncoder",
                new KryoEncoder());
        /*超时检测*/
        ch.pipeline().addLast("readTimeoutHandler",
                new ReadTimeoutHandler(10));
        /*登录应答*/
        ch.pipeline().addLast(new LoginAuthRespHandler());

        /*心跳应答*/
        ch.pipeline().addLast("HeartBeatHandler",
                new HeartBeatRespHandler());

        /*服务端业务处理*/
        ch.pipeline().addLast("ServerBusiHandler",
                new ServerBusiHandler());

    }
}

Add client access station processor

/**
 * @author hdk
 * 类说明:客户端Handler的初始化
 */
public class ClientInit extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        /*剥离接收到的消息的长度字段,拿到实际的消息报文的字节数组*/
        ch.pipeline().addLast("frameDecoder",
                new LengthFieldBasedFrameDecoder(65535,
                        0,2,0,
                        2));

        /*给发送出去的消息增加长度字段*/
        ch.pipeline().addLast("frameEncoder",
                new LengthFieldPrepender(2));

        /*反序列化,将字节数组转换为消息实体*/
        ch.pipeline().addLast(new KryoDecoder());
        /*序列化,将消息实体转换为字节数组准备进行网络传输*/
        ch.pipeline().addLast("MessageEncoder",
                new KryoEncoder());

        /*超时检测*/
        ch.pipeline().addLast("readTimeoutHandler",
                new ReadTimeoutHandler(10));

        /*发出登录请求*/
        ch.pipeline().addLast("LoginAuthHandler",
                new LoginAuthReqHandler());

       /*发出心跳请求*/
        ch.pipeline().addLast("HeartBeatHandler",
                new HeartBeatReqHandler());
    }
}

Processor Considerations

Inbound: Implementation of the inbound necessary ChannelInboundHandler.channelRead next processor in turn triggers a release. Netty release of ByteBuf to another processor reads: ReferenceCountUtil.release (msg); If you do not want to deal with the next processor is called ctx.fireChannelRead (msg);

Outbound: Implementation of the inbound call to the same ChannelOutboundHandler.write ReferenceCountUtil.release (msg), this processor can read processed data in the other processor, if

Processor extension encoder and decoder

An efficient encoding rules defined are important in network programming, submitted to conserve bandwidth transmission efficiency. Increase the transmission speed. Therefore, two special package netty processor called: ByteToMessageDecoder MessageToByteEncoder encoder and decoder. It is also very simple to use, inheritance rewrite decode and encode it ..

Decoder ByteToMessageDecoder

/**
 * @author hdk
 * 类说明:反序列化的Handler
 */
public class KryoDecoder extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in,
                          List<Object> out) throws Exception {
        Object obj = KryoSerializer.deserialize(in);
        //数据信息处理后添加目标编码格式的数据到ByteBuf中就供后面的处理器处理。
        out.add(obj);
    }
}

The encoder MessageToByteEncoder


/**
 * @author hdk
 * 类说明:序列化的Handler
 */
public class KryoEncoder  extends MessageToByteEncoder<MyMessage> {

    @Override
    protected void encode(ChannelHandlerContext ctx, MyMessage message,
                          ByteBuf out) throws Exception {
        KryoSerializer.serialize(message, out);
        //发送ByteBuf到目标IP
        ctx.flush();
    }
}

to sum up

netty why so popular, personally I think that there are several points:

  • 1 event programming code becomes very simple to make.
  • 2 provides many protocols such as mqtt, http, websocket, smtp, redis, etc., all can very quickly we can develop a server program these agreements do not have to go to achieve a.
  • 1563789405876

netty extension - custom protocols

Netty defined message protocol stack consists of two parts: a header, a message body

1563791266642

name Types of length description
crcCode Int 32 Netty message checksum
Length Int 32 The entire message length
sessionID Long 64 Session ID
Type Byte 8 0: 1 Service Request Message: Service Response Message 2: one way service request message handshake message 3 4 5 handshake response message: Heartbeat request message 6: Heartbeat response message
Priority Byte 8 Message priority: 0 ~ 255
Attachment Map<String,Object> lengthen Optional field, since the take forward message header
/**
 * @author hdk
 * 类说明:消息头
 */
public final class MyHeader {

    private int crcCode = 0xabef0101;

    private int length;// 消息长度

    private long sessionID;// 会话ID

    private byte type;// 消息类型

    private byte priority;// 消息优先级

    private Map<String, Object> attachment = new HashMap<String, Object>(); // 附件

    public final int getCrcCode() {
        return crcCode;
    }

    public final void setCrcCode(int crcCode) {
        this.crcCode = crcCode;
    }

    public final int getLength() {
        return length;
    }

    public final void setLength(int length) {
        this.length = length;
    }

    public final long getSessionID() {
        return sessionID;
    }

    public final void setSessionID(long sessionID) {
        this.sessionID = sessionID;
    }

    public final byte getType() {
        return type;
    }

    public final void setType(byte type) {
        this.type = type;
    }

    public final byte getPriority() {
        return priority;
    }

    public final void setPriority(byte priority) {
        this.priority = priority;
    }

    public final Map<String, Object> getAttachment() {
        return attachment;
    }

    public final void setAttachment(Map<String, Object> attachment) {
        this.attachment = attachment;
    }

    @Override
    public String toString() {
        return "MyHeader [crcCode=" + crcCode + ", length=" + length
            + ", sessionID=" + sessionID + ", type=" + type + ", priority="
            + priority + ", attachment=" + attachment + "]";
    }

}
/**
 * @author hdk
 * 类说明:消息实体类
 */
public final class MyMessage {

    private MyHeader myHeader;

    private Object body;

    public final MyHeader getMyHeader() {
        return myHeader;
    }

    public final void setMyHeader(MyHeader myHeader) {
        this.myHeader = myHeader;
    }

    public final Object getBody() {
        return body;
    }

    public final void setBody(Object body) {
        this.body = body;
    }

    @Override
    public String toString() {
        return "MyMessage [myHeader=" + myHeader + "][body="+body+"]";
    }
}

Source

https://github.com/huangdongkui/netty_project

Guess you like

Origin www.cnblogs.com/wolf12/p/11230695.html