zoukankan      html  css  js  c++  java
  • netty——私有协议栈开发案例

    netty——私有协议栈开发案例

    摘要:

    在学习李林峰老师的Netty权威指南中,觉得第十二章《私有协议栈开发》中的案例代码比较有代表性,讲的也不错,但是代码中个人认为有些简单的错误,个人经过简单的修改,编译好后展示给大家,有什么问题,希望留言,共同交流;

    相关包:

    • meven配置:

           <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-all</artifactId>
                <version>5.0.0.Alpha2</version>
            </dependency>
            <dependency>
                <groupId>org.jboss.marshalling</groupId>
                <artifactId>jboss-marshalling-serial</artifactId>
                <version>2.0.0.Beta2</version>
            </dependency>

    • 项目分布

    image

    • 代码

    Nettymessage定义类

    ---------------------------------------------------------------------------------------------------------------------------------------

    public final class  NettyMessage {
        private Header header;
        private Object body;
       
       
        public final Header getHeader() {
            return header;
        }
        public final void setHeader(Header header) {
            this.header = header;
        }
        public final Object getBody() {
            return body;
        }
        public final void setBody(Object body) {
            this.body = body;
        }
       
        public String toString(){
            return "NettyMessage [Header="+header+"]";
        }

    }

    ---------------------------------------------------------------------------------------------------------------------------------------

    消息头定义类

    ---------------------------------------------------------------------------------------------------------------------------------------

    public final class Header {
        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;
        }
       
        public String toString(){
            return "Headder[crcCode=]"+crcCode+",length="+length+",sessionID="
            +sessionID+",type="+type+",priority="+priority+"attachment="+attachment;
        }

    }

    ---------------------------------------------------------------------------------------------------------------------------------------

    定义消息类型

    ---------------------------------------------------------------------------------------------------------------------------------------

    public class MessageType {
        /**
         * 请求
         */
        public final static byte LOGIN_REQ = 0x01;
        /**
         * 回复
         */
        public final static byte LOGIN_RESP = 0x02;
        /**
         * 心跳请求
         */
        public final static byte HEARTBEAT_REQ = 0x03;
        /**
         * 心跳回复
         */
        public final static byte HEARTBEAT_RESP = 0x04;
    }

    ---------------------------------------------------------------------------------------------------------------------------------------

    定义 MarshallingCodeCFactory

    ---------------------------------------------------------------------------------------------------------------------------------------

    import io.netty.handler.codec.marshalling.DefaultMarshallerProvider;
    import io.netty.handler.codec.marshalling.DefaultUnmarshallerProvider;
    import io.netty.handler.codec.marshalling.MarshallerProvider;
    import io.netty.handler.codec.marshalling.UnmarshallerProvider;

    import org.jboss.marshalling.MarshallerFactory;
    import org.jboss.marshalling.Marshalling;
    import org.jboss.marshalling.MarshallingConfiguration;
    /**
    *
    * @ClassName MarshallingCodeCFactory
    * @Description TODOJBoss Marshalling 是一个Java 对象序列化包,对 JDK 默认的序列化框架进行了优化,<br>
    * 但又保持跟 Java.io.Serializable 接口的兼容,同时增加了一些可调的参数和附件的特性,<br>
    * 这些参数和附加的特性, 这些参数和特性可通过工厂类进行配置.  Marshalling 构造工具
    * @author lichunyang
    * @Date 2017年4月13日 下午7:34:31
    * @version 1.0.0
    */
    public class MarshallingCodeCFactory {
       
        public static NettyMarshallingDecoder buildMarshallingDecoder(){
             /*
             * 通过 Marshalling 工具类的 getProvidedMarshallerFactory
             * 静态方法获取MarshallerFactory 实例, , 参数 serial 表示创建的是 Java 序列化工厂对象.它是由
             * jboss-marshalling-serial 包提供
             */
            final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
            /**
             * 创建
             */
            final MarshallingConfiguration configuration = new MarshallingConfiguration();
            configuration.setVersion(5);
            UnmarshallerProvider provider = new DefaultUnmarshallerProvider(marshallerFactory, configuration);
            NettyMarshallingDecoder decoder = new NettyMarshallingDecoder(provider, 1024);// 1024 单个对象最大尺寸
            return decoder;
        }
       
        public static NettyMarshallingEncoder buildMarshallingEncoder(){
            MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
            MarshallingConfiguration configuration = new MarshallingConfiguration();
            configuration.setVersion(5);
            MarshallerProvider provider = new DefaultMarshallerProvider(marshallerFactory, configuration);
            NettyMarshallingEncoder encoder = new NettyMarshallingEncoder(provider);
            return encoder;
        }
    }

    ---------------------------------------------------------------------------------------------------------------------------------------

    定义 NettyMarshallingDecoder和NettyMarshallingEncoder

    ---------------------------------------------------------------------------------------------------------------------------------------

    package netty.codefactory;

    import io.netty.buffer.ByteBuf;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.handler.codec.marshalling.MarshallingDecoder;
    import io.netty.handler.codec.marshalling.UnmarshallerProvider;
    /**
    *
    * @ClassName NettyMarshallingDecoder
    * @Description 扩展MarshallingEncoder 和 MarshallingDecoder,将protected方法编程public可以调用<br>消息解码工具类
    * @author lichunyang
    * @Date 2017年4月13日 下午7:22:03
    * @version 1.0.0
    */
    public class NettyMarshallingDecoder extends MarshallingDecoder {

        public NettyMarshallingDecoder(UnmarshallerProvider provider) {
            super(provider);
        }

        public NettyMarshallingDecoder(UnmarshallerProvider provider, int maxObjectSize) {
            super(provider, maxObjectSize);
        }

        public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
            return super.decode(ctx, in);
        }

    }

    ---------------------------------------------------------------------------------------------------------------------------------------

    package netty.codefactory;

    import io.netty.buffer.ByteBuf;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.handler.codec.marshalling.MarshallerProvider;
    import io.netty.handler.codec.marshalling.MarshallingEncoder;
    /**
    *
    * @ClassName NettyMarshallingEncoder
    * @Description 扩展MarshallingEncoder 和 MarshallingDecoder,将protected方法编程public可以调用<br>消息编码工具类
    * @author lichunyang
    * @Date 2017年4月13日 下午7:20:07
    * @version 1.0.0
    */
    public class NettyMarshallingEncoder extends MarshallingEncoder{

        public NettyMarshallingEncoder(MarshallerProvider provider) {
            super(provider);
        }

        public void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception{
            super.encode(ctx, msg, out);
        }
       
    }

    ---------------------------------------------------------------------------------------------------------------------------------------

    定义 NettyMessageDecoder和NettyMessageEncoder

    ---------------------------------------------------------------------------------------------------------------------------------------

    package netty.codefactory;

    import io.netty.buffer.ByteBuf;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
    import netty.message.Header;
    import netty.message.NettyMessage;

    import java.util.HashMap;
    import java.util.Map;
    /**
    *
    * @ClassName NettyMessageDecoder
    * @Description 解码器
    * @author lichunyang
    * @Date 2017年4月13日 下午7:51:02
    * @version 1.0.0
    */
    public class NettyMessageDecoder extends LengthFieldBasedFrameDecoder{

        private NettyMarshallingDecoder marshallingDecoder;
       
        public NettyMessageDecoder(int maxFrameLength, int lengthFieldOffset,
                int lengthFieldLength,int lengthAdjustment, int initialBytesToStrip) {
            super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip);
            marshallingDecoder = MarshallingCodeCFactory.buildMarshallingDecoder();
        }
       

        public Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception{
            ByteBuf frame = (ByteBuf)super.decode(ctx, in);
            if(frame == null){
                return null;
            }
           
            NettyMessage message = new NettyMessage();
            Header header = new Header();
            header.setCrcCode(frame.readInt());
            header.setLength(frame.readInt());
            header.setSessionID(frame.readLong());
            header.setType(frame.readByte());
            header.setPriority(frame.readByte());
           
            int size = frame.readInt();
            if(size > 0){
                Map<String, Object> attach = new HashMap<String, Object>(size);
                int keySize = 0;
                byte[] keyArray = null;
                String key = null;
                for(int i=0; i<size; i++){
                    keySize = frame.readInt();
                    keyArray = new byte[keySize];
                    in.readBytes(keyArray);
                    key = new String(keyArray, "UTF-8");
                    attach.put(key, marshallingDecoder.decode(ctx, frame));
                }
                key = null;
                keyArray = null;
                header.setAttachment(attach);
            }
            if(frame.readableBytes() > 0){
                message.setBody(marshallingDecoder.decode(ctx, frame));
            }
            message.setHeader(header);
            return message;
        }
    }

  • 相关阅读:
    elementUI的table分页多选,记住上一页并勾选中,:row-key的使用方法
    如何在vue中使用svg
    父子组件传值,子组件接收不到值,并且无法动态更改video的视频源进行视频播放
    vue项目中如何使用dataform向后台传值
    'eslint'不是内部或外部命令,也不是可运行的程序
    小程序点击分享open-type="share"触发父元素怎么解决?
    vue项目启动报错Module build failed: Error: No PostCSS Config found in:
    eslint在webstorm中有错误警告
    微信小程序 image图片组件实现宽度固定 高度自适应
    JAVA设计模式学习--代理模式
  • 原文地址:https://www.cnblogs.com/lichunyang321/p/6713363.html
Copyright © 2011-2022 走看看