Netty4.0 开发指导 2

Netty4.0 开发指导 2

原文: http://netty.io/wiki/user-guide-for-4.x.html

聊一下用POJO代替ByteBuf

到目前为止我们点评的所有代码实例都使用ByteBuf作为主要的消息格式. 在这一章节, 我们将改进TIME协议的客户端和服务端去使用POJO代替ByteBuf.
使用POJO在你的ByteBuf是显尔易见的; 通过从处理单元中分离从ByteBuf提取信息的代码你的处理单元更容易维护和重用性更高. 在TIME的实例中, 我们只是读一个32位整型数字, 这个不是直接使用ByteBuf的主要问题. 然而, 你将发现分离你实现的一个真实的通信协议是很有必要的.
首先, 让我们定义一个新的类型就叫UnixTime.

01 package io.netty.example.time;
02  
03 import java.util.Date;
04  
05 public class UnixTime {
06  
07     private final int value;
08      
09     public UnixTime() {
10         this((int) (System.currentTimeMillis() / 1000L + 2208988800L));
11     }
12      
13     public UnixTime(int value) {
14         this.value = value;
15     }
16          
17     public int value() {
18         return value;
19     }
20          
21     @Override
22     public String toString() {
23         return new Date((value() - 2208988800L) * 1000L).toString();
24     }
25 }


我们调整一下TimeDecoder去产生一个UnixTime而不是ByteBuf.

1 @Override
2 protected Object decode(ChannelHandlerContext ctx, ByteBuf in, MessageList<Object> out) {
3     if (in.readableBytes() < 4) {
4         return;
5     }
6  
7     out.add(new UnixTime(buffer.readInt());
8 }


随着解码码更新完成, TimeClientHandler不再使用ByteBuf所以我们需要改一下去接收一个UnixTime类型的消息. 

1 @Override
2 public void messageReceived(ChannelHandlerContext ctx, MessageList<Object> msgs) {
3     UnixTime m = (UnixTime) msgs.get(0);
4     System.out.println(m);
5     ctx.close();
6 }

更简单和优雅, 对吗? 同样的技术可以应用的服务端. 让我们再更新一下TimeServerHandler: 

1 @Override
2 public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
3     ChannelFuture f = e.getChannel().write(new UnixTime());
4     f.addListener(ChannelFutureListener.CLOSE);
5 }

现在唯一缺少的一块是编码器,  这是一个ChannelOutboundHandler的实现, 他将UnixTime转换为ByteBuf. 比写一个解码器还要简单因为当编码消息时不需要处理分包和装配的问题.  

01 package io.netty.example.time;
02  
03 public class TimeEncoder extends ChannelOutboundHandlerAdapter {
04     @Override
05     public void write(ChannelHandlerContext ctx, MessageList<Object> msgs, ChannelPromise promise) {
06         MessageList<ByteBuf> out = MessageList.newInstance();
07         for (UnixTime m: msgs.<UnixTime>cast()) {
08             ByteBuf encoded = ctx.alloc().buffer(4);
09             encoded.writeInt(m.value());
10             out.add(encoded);
11         }
12         msgs.releaseAllAndRecycle();
13         ctx.write(out, promise); // (1)
14     }
15 }

1. 注意这里我们传进去一个原始参数ChannelPromise, 当数据真正写入后Netty用他来标记成功还是失败.  
甚至可以进一步简化, 你可以用MessageToByteEncoder: 

1 public class TimeEncoder extends MessageToByteEncoder<UnixTime> {
2     @Override
3     protected void encode(ChannelHandlerContext ctx, UnixTime msg, ByteBuf out) {
4         out.writeInt(msg.value());
5     }
6 }

最后留下的任务是在服务端插入TimeEncoder到ChannelPipeline.

关闭你的程序

通过shutdownGracefully()方法关闭Netty程序可以像关闭你创建的EventLoopGroup一样简单. 他返回一个Future, 当EventLoopGroup中断完成后通知你并且属于"boss"和"worker"组的所有channel会被关闭. 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值