Netty入门实例-使用POJO代替ByteBuf
到目前为止,我们上面几篇教程中的所有例子都使用ByteBuf作为协议消息的主要数据结构。 在本节中,我们将改进TIME协议的客户端和服务器示例,让它们使用POJO来代替原来的ByteBuf。
在ChannelHandler
中使用POJO的优点是显而易见的; 处理程序将从ByteBuf中提取信息的代码,将从处理程序中分离出来,变得更易维护和可重用。 在TIME客户端和服务器示例中,我们只读取一个32位整数,它不是直接使用ByteBuf来解码转换的。在实现真实世界协议时,这是必须要进行分离的。
首先,我们定义一个名为 UnixTime
的新类型(一个简单的Java类)。
package cn.netty.timepojo; import java.util.Date;public class UnixTime { private final long value; public UnixTime() { this(System.currentTimeMillis() / 1000L + 2208988800L); } public UnixTime(long value) { this.value = value; } public long value() { return value; } @Override public String toString() { Date date = new Date((value() - 2208988800L) * 1000L); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateString = formatter.format(date); return dateString; } }
我们现在来修改时间解码器(TimeDecoder
)来生成UnixTime
,而不是ByteBuf
。
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) { if (in.readableBytes() < 4) { return; } out.add(new UnixTime(in.readUnsignedInt())); }
使用更新的解码器,TimeClientHandler
不再使用ByteBuf:
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) { UnixTime m = (UnixTime) msg; System.out.println(m); ctx.close(); }
怎么样?看起更简单和优雅,对吧? 相同地也可以应用在服务器端。现在我们首先更新TimeServerHandler
中的代码:
@Override public void channelActive(ChannelHandlerContext ctx) { ChannelFuture f = ctx.writeAndFlush(new UnixTime()); f.addListener(ChannelFutureListener.CLOSE); }
现在,唯一缺少的是一个编码器,它是一个ChannelOutboundHandler
的实现,是将UnixTime
转换回ByteBuf
。 它比编写解码器简单得多,因为在编码消息时不需要处理数据包分段和组合。
package cn.sxt.netty.timepojo; public class TimeEncoder extends ChannelOutboundHandlerAdapter { @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) { UnixTime m = (UnixTime) msg; ByteBuf encoded = ctx.alloc().buffer(4); encoded.writeInt((int)m.value()); ctx.write(encoded, promise); // (1) } }
在这一行有很多重要的东西。
首先,我们按原样传递原始的ChannelPromise
,以便Netty将编码数据实际写入时将其标记为成功或失败。
第二步,我们没有调用ctx.flush()
。 有一个单独的处理程序方法void flush(ChannelHandlerContext ctx)
,它用于覆盖flush()
操作。
要进一步简化,可以使用MessageToByteEncoder
:
public class TimeEncoder extends MessageToByteEncoder<UnixTime> { @Override protected void encode(ChannelHandlerContext ctx, UnixTime msg, ByteBuf out) { out.writeInt((int)msg.value()); } }
剩下的最后一个任务是在TimeServerHandler
之前将TimeEncoder
插入到服务器端的ChannelPipeline
中,这里将留作一个简单的练习吧。
相关知识点
开源项目
知识点
相关教程
更多Netty入门实例-时间服务器
Netty中服务器和客户端之间最大的和唯一的区别是使用了不同的Bootstrap和Channel实现
Netty入门实例-编写服务器端程序
channelRead()处理程序方法实现如下
Spring boot入门实例
入门实例是基于maven工程,主要配置: spring boot 父节点依赖,引入这个之后相关的引入就不需要添加version配置,spring boot会自动选择最合适的版本进行添加。 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-s
vue 入门实例
solr入门之SolrServer实例化方式
solr入门之SolrServer实例化方式 (2013-06-19 18:04:14) 转载▼ 随着solr版本的不断升级, 差异越来越大, 从以前的 solr1.2 到现在的 solr4.3, 无论是类还是功能都有很大的变换,为了能及时跟上新版本的步伐, 在此将新版本的使用做一个简单的入门说明: Solr3.6版本 SolrServer实例化类型有httpClient,和本
Activiti入门程序-启动流程实例
RuntimeService:执行管理,包括启动、推进、删除流程实例等操作 RuntimeService是activiti的流程执行服务类。可以从这个服务类中获取很多关于流程执行相关的信息 调用processEngine的getRuntimeService方法获取RuntimeService对象 调用RuntimeService的相关方法可以启动流程实例有以下方法 启动流程实例示例程序: /*
iText生成PDF入门实例
最近想把网站的文章导出为PDF文件,所以又得学学怎样导出PDF。iText是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF文档,而且可以将HTML网页转化为PDF文件,同时它可以很方便的和web或者其他应用整合使用。
Spring MVC 入门实例教程
[Netty 1] 初识Netty
1. 简介 最早接触netty是在阅读Zookeeper源码的时候,后来看到Storm的消息传输层也由ZMQ转为Netty,所以决心好好来研究和学习一下netty这个框架。 Netty项目地址:http://netty.io/index.html Github项目: https://github.com/netty/netty Netty是一个异步的、事件驱动的网络应用框架,基于它能够快速开发高性
Lucene学习笔记之四:lucene入门实例
根据Lucene学习笔记之三:全文搜索详解,搭建lucene入门实例。主要内容包括建立索引和搜索,分词贯穿其中。lucene建立索引,信息源:要采集,必须有信息源,在这里我们就以读取硬盘中一个文件夹下所有的文件(File)充当信息源。
Activiti入门程序-查看历史实例信息
HistoryService:查询历史信息的服务。在一个流程执行完成后,这个对象为我们提供查询历史信息。 历史实例查询包括: 1、历史流程实例查询 HistoricProcessInstanceQuery HistoricProcessInstanceQuery hpiQuery = service.createHistoricProcessInstanceQuery(); 2、查
构建Disruptor实例-生产消费模型完成整个入门示例
初始化Disruptor,构建Disruptor只要需要以下几个参数:1 eventFactory: 消息(event)工厂对象,2 ringBufferSize: 容器的长度,3 executor: 线程池(建议使用自定义线程池) RejectedExecutionHandler,4 ProducerType: 单生产者 还是 多生产者, 5 waitStrategy: 等待策略2、初始化好Disruptor之后,通过该对象的handleEventsWith添加消费者的监听。3、然后启动D...
Netty环境配置
netty是一个java事件驱动的网络通信框架,也就是一个jar包,只要在项目里引用即可。
Hadoop入门—Linux下伪分布式计算的安装与wordcount的实例展示
开始研究一下开源项目Hadoop,因为根据本人和业界的一些分析,海量数据的分布式并行处理是趋势,咱不能太落后,虽然开始有点晚,呵呵。首先就是安装和一个入门的小实例的讲解,这个恐怕是我们搞软件开发的,最常见也最有效率地入门一个新鲜玩意的方式了,废话不多说开始吧。 本人是在Ubuntu下进行实验的,java和ssh安装就不在这里讲了,这两个是必须要安装的,好了我们进入主题安装hadoop: 1.下载h
Netty开发环境配置
最新版本的Netty 4.x和JDK 1.6及更高版本
最新教程
更多java线程状态详解(6种)
java线程类为:java.lang.Thread,其实现java.lang.Runnable接口。 线程在运行过程中有6种状态,分别如下: NEW:初始状态,线程被构建,但是还没有调用start()方法 RUNNABLE:运行状态,Java线程将操作系统中的就绪和运行两种状态统称为“运行状态” BLOCK:阻塞状态,表示线程阻塞
redis从库只读设置-redis集群管理
默认情况下redis数据库充当slave角色时是只读的不能进行写操作,如果写入,会提示以下错误:READONLY You can't write against a read only slave. 127.0.0.1:6382> set k3 111 (error) READONLY You can't write against a read only slave. 如果你要开启从库
Netty环境配置
netty是一个java事件驱动的网络通信框架,也就是一个jar包,只要在项目里引用即可。
Netty基于流的传输处理
在TCP/IP的基于流的传输中,接收的数据被存储到套接字接收缓冲器中。不幸的是,基于流的传输的缓冲器不是分组的队列,而是字节的队列。 这意味着,即使将两个消息作为两个独立的数据包发送,操作系统也不会将它们视为两个消息,而只是一组字节(有点悲剧)。 因此,不能保证读的是您在远程定入的行数据
Netty入门实例-时间服务器
Netty中服务器和客户端之间最大的和唯一的区别是使用了不同的Bootstrap和Channel实现
Netty入门实例-编写服务器端程序
channelRead()处理程序方法实现如下
Netty开发环境配置
最新版本的Netty 4.x和JDK 1.6及更高版本
电商平台数据库设计
电商平台数据库表设计:商品分类表、商品信息表、品牌表、商品属性表、商品属性扩展表、规格表、规格扩展表
HttpClient 上传文件
我们使用MultipartEntityBuilder创建一个HttpEntity。 当创建构建器时,添加一个二进制体 - 包含将要上传的文件以及一个文本正文。 接下来,使用RequestBuilder创建一个HTTP请求,并分配先前创建的HttpEntity。
MongoDB常用命令
查看当前使用的数据库 > db test 切换数据库 > use foobar switched to db foobar 插入文档 > post={"title":"领悟书生","content":"这是一个分享教程的网站","date":new
快速了解MongoDB【基本概念与体系结构】
什么是MongoDB MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era. MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
windows系统安装MongoDB
安装 下载MongoDB的安装包:mongodb-win32-x86_64-2008plus-ssl-3.2.10-signed.msi,按照提示步骤安装即可。 安装完成后,软件会安装在C:\Program Files\MongoDB 目录中 我们要启动的服务程序就是C:\Program Files\MongoDB\Server\3.2\bin目录下的mongod.exe,为了方便我们每次启动,我
Spring boot整合MyBatis-Plus 之二:增删改查
基于上一篇springboot整合MyBatis-Plus之后,实现简单的增删改查 创建实体类 添加表注解TableName和主键注解TableId import com.baomidou.mybatisplus.annotations.TableId; import com.baomidou.mybatisplus.annotations.TableName; import com.baom
分布式ID生成器【snowflake雪花算法】
基于snowflake雪花算法分布式ID生成器 snowflake雪花算法分布式ID生成器几大特点: 41bit的时间戳可以支持该算法使用到2082年 10bit的工作机器id可以支持1024台机器 序列号支持1毫秒产生4096个自增序列id 整体上按照时间自增排序 整个分布式系统内不会产生ID碰撞 每秒能够产生26万ID左右 Twitter的 Snowflake分布式ID生成器的JAVA实现方案
Spring boot整合mybatis plus
快速了解mybatis plus 是对Mybatis框架的二次封装和扩展 纯正血统:完全继承原生 Mybatis 的所有特性 最少依赖:仅仅依赖Mybatis以及Mybatis-Spring 性能损耗小:启动即会自动注入基本CURD ,性能无损耗,直接面向对象操作 自动热加载:Mapper对应的xml可以热加载,大大减少重启Web服务器时间,提升开发效率 性能分析:自带Sql性能分析插件,开发测试