netty4 实现自定义协议开发

netty4实现自定义协议开发

本示例使用的是最新netty4.1.8 参考excmples (securechat)

  • 消息格式定义
  • 编码器
  • 解码器
  • 示例指令
  • 源码

本示例协议头部使用12个字节来定义具体如下:
一个字节的标记和类型,一个字节的error code,2个字节的传输序列号,2个字节的code,2个字节的传输长度,后续4个字节的扩展码。
头部定义如下:

    private byte flagBean;
    private byte error;
    private byte type;
    private short command;
    private short seq;
    private short length;
    private byte extend1;
    private byte extend2;
    private short extend3;

编码器定义如下:

import netty.core.bean.ProtocolHeader;
import netty.core.bean.ProtocolMsg;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

public class ProtocolEncoder extends MessageToByteEncoder<ProtocolMsg> {

    @Override
    protected void encode(ChannelHandlerContext paramChannelHandlerContext,
            ProtocolMsg in, ByteBuf out) throws Exception {
        System.out.println("encode");
            ProtocolHeader header = in.getHeader();
            out.writeByte(header.getFlag()|header.getError());
            out.writeByte(header.getType());
            out.writeShort(header.getCommand());
            out.writeShort(header.getSeq());
            if(in.getBody().length() > 0){
                out.writeShort(in.getBody().length());
            }else{
                out.writeShort(0);
            }
            out.writeBytes(in.getBody().getBytes());
    }
}

解码器定义如下:


import java.util.List;

import netty.core.bean.ProtocolHeader;
import netty.core.bean.ProtocolMsg;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.CharsetUtil;

public class ProtocolDecoder extends ByteToMessageDecoder{

    @Override
    protected void decode(ChannelHandlerContext paramChannelHandlerContext,
            ByteBuf in, List out) throws Exception {
         if (in.readableBytes()<8) { 
                return; //小于头部8字节不做处理  
            }  
            ProtocolHeader header = new ProtocolHeader();
            ProtocolMsg msg = new  ProtocolMsg();
            byte flagType = in.readByte();
            header.setFlag((byte) (flagType&0x0f));
            header.setError((byte) (flagType&0xf0));
            header.setType(in.readByte());
            header.setCommand(in.readShort());
            header.setSeq(in.readShort());
            header.setLength(in.readShort());
            in.markReaderIndex();  
            if(in.readableBytes()return;
            }
            byte[] msgs = new byte[header.getLength()];
            in.readBytes(msgs);
            msg.setHeader(header);
            msg.setBody(new String(msgs,CharsetUtil.UTF_8));
            out.add(msg);   
    }
} 
  

示例请求命令如下:


import io.netty.channel.Channel;
import netty.core.bean.FlagBean;
import netty.core.bean.ProtocolHeader;
import netty.core.bean.ProtocolMsg;

import com.alibaba.fastjson.JSONObject;

public class Command {

    public static void authLogin(Channel channel,String userName,String password,short seq){
        JSONObject auth = new JSONObject();
        auth.put("userName", userName);
        auth.put("password", password);
        ProtocolHeader header = new ProtocolHeader();
        FlagBean flag = new FlagBean((byte)1,(byte)4, (byte)8);
        header.setFlag(flag.getFlagBean());
        header.setType(CommandTypeEnum.REQUEST_TYPE.getValue());
        header.setError((byte)0);
        header.setSeq(seq);
        header.setCommand((short)1);
        header.setLength((short)auth.toJSONString().length());
        ProtocolMsg msg = new  ProtocolMsg();
        msg.setHeader(header);
        msg.setBody(auth.toJSONString());
        channel.writeAndFlush(msg);

    }
}

如需要完整demo ,留言我会发给大家。


[2]: Netty权威指南 第2版

你可能感兴趣的:(java)