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>

  • 项目分布

  • 代码

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;
    }
}

netty——私有协议栈开发案例的更多相关文章

  1. 真正实现Netty私有协议开发

    首先<Netty权威指南>私有协议开发那一章的样例代码是编译不通过的(但是这丝毫不影响本书的价值)处理方案可以参考:http://www.itnose.net/detail/6112870 ...

  2. netty 私有协议栈

    通信协议从广义上区分,可以分为公有协议和私有协议.由于私有协议的灵活性,它往往会在某个公司或者组织内部使用,按需定制,也因为如此,升级起来会非常方便,灵活性好.绝大多数的私有协议传输层都基于TCP/I ...

  3. Netty私有协议栈 读书笔记

    1.数据结构定义 1)netty消息:NettyMessage package com.cherry.netty.demo.protocolstack.pojo; import com.cherry. ...

  4. 基于netty http协议栈的轻量级流程控制组件的实现

    今儿个是冬至,所谓“冬大过年”,公司也应景五点钟就放大伙儿回家吃饺子喝羊肉汤了,而我本着极高的职业素养依然坚持留在公司(实则因为没饺子吃没羊肉汤喝,只能呆公司吃食堂……).趁着这一个多小时的时间,想跟 ...

  5. 简易RPC框架-私有协议栈

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  6. 基于Netty的私有协议栈的开发

    基于Netty的私有协议栈的开发 书是人类进步的阶梯,每读一本书都使自己得以提升,以前看书都是看了就看了,当时感觉受益匪浅,时间一长就又还回到书本了!所以说,好记性不如烂笔头,以后每次看完一本书都写一 ...

  7. netty(5)高级篇-私有协议栈

    来源:<Netty权威指南>  作者:李林峰 一.私有协议介绍 由于现代软件的复杂性,一个大型软件系统往往会被人为地拆分称为多个模块,另外随着移动互联网的兴起,网站的规模越来越大,业务功能 ...

  8. HTTP协议开发应用-HTTP&XML协议栈开发

    Netty HTTP+XML协议栈开发 由于HTTP协议的通用性,很多异构系统间的通信交互采用HTTP协议,通过HTTP协议承载业务数据进行消息交互,例如非常流行的HTTP+XML或者RESTful+ ...

  9. AllJoyn+Android开发案例-android跨设备调用方法

    AllJoyn+Android开发案例-android跨设备调用方法 项目须要涉及AllJoyn开源物联网框架.前面主要了解了一些AllJoyn主要的概念.像总线,总线附件,总线对象,总线接口这种概念 ...

随机推荐

  1. TypeScript设计模式之门面、适配器

    看看用TypeScript怎样实现常见的设计模式,顺便复习一下. 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想 ...

  2. BOM基础(一)

    学完了js的基础语法和DOM之后,就要要看看javascript中最后一项BOM了.BOM,全称brower document model,翻译过来就是浏览器对象模型.DOM是文档对象模型,属于BOM ...

  3. 【杂】poj2482 Stars in Your Windows 题面的翻译

    原地址:http://poj.org/problem?id=2482 神题,被誉为最浪漫的题目,一位acmer以自己独特的方式写下的殷殷情语 你窗前的星星 纵时光飞逝如梭,也我对你的回忆也永不黯然.从 ...

  4. Compare Version Numbers leetcode

    Compare two version numbers version1 and version2.If version1 > version2 return 1, if version1 &l ...

  5. Hibernate二级缓存原理

    缓存:缓存是什么,解决什么问题? 位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之为缓存Cache.缓存目的:让数据更接近于应用程序,协调速度不匹配,使访问速度更快 ...

  6. 3403: [Usaco2009 Open]Cow Line 直线上的牛

    3403: [Usaco2009 Open]Cow Line 直线上的牛 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 71  Solved: 62[S ...

  7. Codevs2018 反病毒软件

    2018 反病毒软件 时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond  查看运行结果   题目描述 Description 其实这个“反病毒软件”(Anti ...

  8. 关于wxpython多线程研究包括(import Publisher错误研究)

    作为一个自动化测试人员,开发基本的应用桌面程序是必须的!最近在研究wxpython相关知识,目前看到多线程一块,发现官方文档介绍说:"在线程中不能修改修改窗口属性!",但是实际情况 ...

  9. Octave Tutorial(《Machine Learning》)之第四课《绘图数据》

    第四课 Plotting Data 绘图数据 t = [0,0.01,0.98]; y1 = sin(2*pi*4*t); y2 = cos(2*pi*4*t); plot(t,y1);(绘制图1) ...

  10. Json 与GeoJson

    1.JSON介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.简单地说,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后 ...