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>
- 项目分布

- 代码
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——私有协议栈开发案例的更多相关文章
- 真正实现Netty私有协议开发
首先<Netty权威指南>私有协议开发那一章的样例代码是编译不通过的(但是这丝毫不影响本书的价值)处理方案可以参考:http://www.itnose.net/detail/6112870 ...
- netty 私有协议栈
通信协议从广义上区分,可以分为公有协议和私有协议.由于私有协议的灵活性,它往往会在某个公司或者组织内部使用,按需定制,也因为如此,升级起来会非常方便,灵活性好.绝大多数的私有协议传输层都基于TCP/I ...
- Netty私有协议栈 读书笔记
1.数据结构定义 1)netty消息:NettyMessage package com.cherry.netty.demo.protocolstack.pojo; import com.cherry. ...
- 基于netty http协议栈的轻量级流程控制组件的实现
今儿个是冬至,所谓“冬大过年”,公司也应景五点钟就放大伙儿回家吃饺子喝羊肉汤了,而我本着极高的职业素养依然坚持留在公司(实则因为没饺子吃没羊肉汤喝,只能呆公司吃食堂……).趁着这一个多小时的时间,想跟 ...
- 简易RPC框架-私有协议栈
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- 基于Netty的私有协议栈的开发
基于Netty的私有协议栈的开发 书是人类进步的阶梯,每读一本书都使自己得以提升,以前看书都是看了就看了,当时感觉受益匪浅,时间一长就又还回到书本了!所以说,好记性不如烂笔头,以后每次看完一本书都写一 ...
- netty(5)高级篇-私有协议栈
来源:<Netty权威指南> 作者:李林峰 一.私有协议介绍 由于现代软件的复杂性,一个大型软件系统往往会被人为地拆分称为多个模块,另外随着移动互联网的兴起,网站的规模越来越大,业务功能 ...
- HTTP协议开发应用-HTTP&XML协议栈开发
Netty HTTP+XML协议栈开发 由于HTTP协议的通用性,很多异构系统间的通信交互采用HTTP协议,通过HTTP协议承载业务数据进行消息交互,例如非常流行的HTTP+XML或者RESTful+ ...
- AllJoyn+Android开发案例-android跨设备调用方法
AllJoyn+Android开发案例-android跨设备调用方法 项目须要涉及AllJoyn开源物联网框架.前面主要了解了一些AllJoyn主要的概念.像总线,总线附件,总线对象,总线接口这种概念 ...
随机推荐
- Selenium 切换句柄
最近用了网络上别人的一段切换窗口的code每次成功了,不错,学习 // 根据Title切换新窗口 public boolean switchToWindow_Title(WebDriver drive ...
- 图片流量节省大杀器:基于腾讯云CDN的sharpP自适应图片技术实践
目前移动端运营素材大部分依赖图片,基于对图片流量更少,渲染速度更快的诉求,我们推动CDN,X5内核,即通产品部共同推出了一套业务透明,无痛接入的CDN图片优化方案:基于CDN的sharpP自适应图片无 ...
- 20155304 2016-2017-2 《Java程序设计》第三周学习总结
20155304 2016-2017-2 <Java程序设计>第三周学习总结 教材学习内容总结 第四章 类与对象 定义: 对象(Object):存在的具体实体,具有明确的状态和行为. 类( ...
- ThinkPhp框架:父类及表单验证
这个知识点,就可以通过"登录"和"注册"的页面来学习这个知识点了首先先做一个"登录"功能一.登录功能(父类)(1)登录的控制器在我的控制器文 ...
- 3400: [Usaco2009 Mar]Cow Frisbee Team 奶牛沙盘队
3400: [Usaco2009 Mar]Cow Frisbee Team 奶牛沙盘队 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 129 Solv ...
- javascript-基本数据类型和转换
ECMAScript中有5种基本数据类型:Undefined.Null.Boolean.Number.String.还有1种复杂数据类型-Object,Object实质上是由一组无序的名值对(键值对) ...
- 如何使用Vue2做服务端渲染
花费了一个月时间,终于在新养车之家项目中成功部署了vue2服务端渲染(SSR),并且使用上了Vuex 负责状态管理,首屏加载时间从之前4G网络下的1000ms,提升到了现在500-700ms之间,SS ...
- PHP后台程序员工作到如今的一点心得
一个项目的建立,一开始一定要有需求文档,没有需求文档的项目注定会改来改去.还被骂的很惨.要时刻牢记一句话:口说无凭,有文档为证. 第一:开发语言的选择,PHP,当然还有JAVA,.NET你做的项目当然 ...
- Python中闭包、装饰器的概念
1.闭包(Closure)的概念: 内部函数中对enclosing作用域的变量进行引用 1 passline = 60 2 def func(val): 3 print('%x' % id(val)) ...
- Web API框架学习——消息管道(二)
HttpServer的GlobalConfiguration中创建: GlobalConfiguration中确定了第一个HttpMessageHandler消息管道: 首:DefaultServer ...