Netty5入门(2)

四、Time协议

继续测试《netty5用户指南》中的Time协议。

1、一个封装时间的特殊的POJO类

首先实现UnixTime类:

package com.ydtf;

import java.util.Date;

public class UnixTime {

private final int value;

public UnixTime() {

this((int) (System.currentTimeMillis() / 1000L+ 2208988800L));

}

public UnixTime(int value) {

this.value = value;

}

public int value() {

return value;

}

@Override

public String toString() {

return new Date((value() - 2208988800L) *1000L).toString();

}

}

2、将ByteBuf转换为POJO

然后是TimeDecoder类:

package com.ydtf;

import java.util.List;

import io.netty.buffer.ByteBuf;

import io.netty.channel.ChannelHandlerContext;

import io.netty.handler.codec.ByteToMessageDecoder;

public class TimeDecoder extends ByteToMessageDecoder { // (1)

@Override

protected void decode(ChannelHandlerContext ctx, ByteBuf in,

List<Object>out) throws Exception {

if (in.readableBytes()< 4) {

return;

}

out.add(new UnixTime(in.readInt()));

}

}

3、将POJO转换为ByteBuf

TimeEncoder,用于进行UnixTime –>ByteBuf的转换。

package com.ydtf;

import io.netty.buffer.ByteBuf;

import io.netty.channel.ChannelHandlerContext;

import io.netty.handler.codec.MessageToByteEncoder;

public class TimeEncoder extends MessageToByteEncoder<UnixTime> {

@Override

protected void encode(ChannelHandlerContext ctx, UnixTime msg, ByteBuf out)

throws Exception {

out.writeInt(msg.value());

}

}

4、服务端的处理

然后是服务端的handler:

package com.ydtf;

import io.netty.buffer.ByteBuf;

import io.netty.channel.ChannelFuture;

import io.netty.channel.ChannelFutureListener;

import io.netty.channel.ChannelHandlerAdapter;

import io.netty.channel.ChannelHandlerContext;

public classTimeServerHandler extendsChannelHandlerAdapter {

@Override

public voidchannelActive(ChannelHandlerContext ctx) {

ChannelFuture f = ctx.writeAndFlush(new UnixTime());

f.addListener(ChannelFutureListener.CLOSE);

}

@Override

public voidexceptionCaught(ChannelHandlerContext ctx, Throwable cause) {

cause.printStackTrace();

ctx.close();

}

}

5、客户端的处理

客户端的handler:

package com.ydtf;

import io.netty.channel.ChannelHandlerAdapter;

import io.netty.channel.ChannelHandlerContext;

public classTimeClientHandler extendsChannelHandlerAdapter {

@Override

public voidchannelRead(ChannelHandlerContext ctx, Object msg) {

UnixTime m = (UnixTime) msg;

System.out.println(m);

ctx.close();

}

@Override

public voidexceptionCaught(ChannelHandlerContext ctx, Throwable cause) {

cause.printStackTrace();

ctx.close();

}

}

6、服务端主类

package com.ydtf;

import io.netty.bootstrap.ServerBootstrap;

import io.netty.channel.ChannelFuture;

import io.netty.channel.ChannelInitializer;

import io.netty.channel.ChannelOption;

import io.netty.channel.EventLoopGroup;

import io.netty.channel.nio.NioEventLoopGroup;

import io.netty.channel.socket.SocketChannel;

importio.netty.channel.socket.nio.NioServerSocketChannel;

public class TimeServer {

private int port;

public TimeServer(int port) {

this.port = port;

}

public void run() throws Exception {

EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)

EventLoopGroup workerGroup = new NioEventLoopGroup();

try {

ServerBootstrap b = new ServerBootstrap(); // (2)

b.group(bossGroup, workerGroup)

.channel(NioServerSocketChannel.class) // (3)

.childHandler(newChannelInitializer<SocketChannel>() { // (4)

@Override

public voidinitChannel(SocketChannel ch) throws Exception {

ch.pipeline().addLast(new TimeEncoder(), new TimeServerHandler());

}

})

.option(ChannelOption.SO_BACKLOG, 128)          // (5)

.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)

ChannelFuture f = b.bind(port).sync(); // (7)

f.channel().closeFuture().sync();

} finally {

workerGroup.shutdownGracefully();

bossGroup.shutdownGracefully();

}

}

public static void main(String[] args) throws Exception {

int port;

if (args.length > 0) {

port = Integer.parseInt(args[0]);

} else {

port = 8080;

}

new TimeServer(port).run();

}

}

7、客户端主类

packagecom.ydtf;

importio.netty.bootstrap.Bootstrap;

importio.netty.channel.ChannelFuture;

importio.netty.channel.ChannelInitializer;

import io.netty.channel.ChannelOption;

importio.netty.channel.EventLoopGroup;

importio.netty.channel.nio.NioEventLoopGroup;

importio.netty.channel.socket.SocketChannel;

importio.netty.channel.socket.nio.NioSocketChannel;

publicclass TimeClient {

public static void main(String[] args)throws Exception {

String host = args[0];

int port = Integer.parseInt(args[1]);

EventLoopGroup workerGroup = newNioEventLoopGroup();

try {

Bootstrap b = new Bootstrap(); //(1)

b.group(workerGroup); // (2)

b.channel(NioSocketChannel.class);// (3)

b.option(ChannelOption.SO_KEEPALIVE, true); // (4)

b.handler(newChannelInitializer<SocketChannel>() {

@Override

public voidinitChannel(SocketChannel ch) throws Exception {

ch.pipeline().addLast(newTimeDecoder(), new TimeClientHandler());

}

});

// Start the client.

ChannelFuture f = b.connect(host,port).sync(); // (5)

// Wait until the connection isclosed.

f.channel().closeFuture().sync();

} finally {

workerGroup.shutdownGracefully();

}

}

}

8、运行

在TimeServer.java上右键,Run as >> Java Application,启动服务端。

然后在TimeClient.java上右键,Run as >> Run Configurations…,在弹出的窗口中设置Name和Main Class:

Name设置一个和现有配置不重复的就可以了,比如TimeClient1、TimeClien(2)等。点击Mainclass右边的Search…按钮,选择TimeClient类。

然后点Arguments,添加两个运行参数localhost和8080:

然后点击窗口右下角的Run按钮。这是你将在客户端的Console窗口中看见一个日期输出。

如果想分别查看服务端和客户端的Console输出,请点击Display Selected Console按钮:

时间: 2024-11-03 05:29:54

Netty5入门(2)的相关文章

Netty5入门(1)

一.     搭建开发环境 本教程使用的开发环境为MacOSX 10.10+JDK1.8+Eclipse Java EE IDE4.4.1+Maven3.2.5.以下是开发环境的搭建过程. 1. 安装JDK 1.8 本教程使用的JDK版本为JDK1.8.你可以在http://java.com下载到这个最新的JDK. JDK的安装配置就不用多说了,你明白的. 2. 安装Eclipse Java EE 本教程使用Eclipse为Eclipse Java EE 4.4.1,你可以在http://www

Netty5入门(3)

一.示例介绍 示例取自<基于Netty5.0高级案例一之NettyWebsocket>,和<Netty inAction>中11章的例子一样,这个例子通过WebSocket实现了一个聊天室的群发功能.但后者的例子我没本事跑通. 新建一个Maven项目,项目名称叫NettyWebSocket,具体过程请参考前一贴.别忘了在pom.xml中加入netty5.0的依赖. 在项目中新建4个class: 4个类的代码你可以从后面的内容中找到,这里先不考虑代码的问题.用"复制>

Netty5入门学习笔记001

Netty官网:http://netty.io/ 本例程使用最新的netty5.x版本编写 服务器端: TimeServer 时间服务器 服务端接收客户端的连接请求和查询当前时间的指令,判断指令正确后响应返回当前服务器的校准时间. package c1; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializ

netty5入门教程0

1.Netty是什么? 本质:JBoss做的一个Jar包 目的:快速开发高性能.高可靠性的网络服务器和客户端程序 优点:提供异步的.事件驱动的网络应用程序框架和工具 通俗的说:一个好使的处理Socket的东东 2.Netty的异步事件驱动模型主要涉及到下面几个核心的概念   Channel:表示一个与socket关联的通道  ChannelPipeline: 管道,一个Channel拥有一个ChannelPipeline,ChannelPipeline维护着一个处理链(严格的说是两 个:upst

Netty5入门学习笔记004-使用Netty传输POJO对象(上)

使用Netty传输POJO对象,重点在于对象的序列化,序列化后的对象可以通过TCP流进行网络传输,结合Netty提供的对象编解码器,可以做到远程传输对象. 下面我们来看一个例子:模拟订票 首先Java序列化的POJO对象需要实现java.io.Serializable接口. 火车车次和余票量POJO: package bookticket; import java.io.Serializable; /**  * 火车pojo对象  * @author xwalker  */ public cla

Netty5入门学习笔记003-TCP粘包/拆包问题的解决之道(下)

TCP网络通信时候会发生粘包/拆包的问题,上节使用定长解码器解码,本次使用Netty提供的特殊分隔符解码器 还是用上节中的代码例子,但是只需要修改一下发送的消息和配置一下解码器就可以了 客户端发送消息中添加分隔符做为指令的结束符,模拟多条指令粘包发出 服务器配置分隔符解码器使用&符号拆包 运行结果: 服务器使用分隔符解码器成功拆包. 当然还有更复杂的自定义协议处理TCP粘包/拆包问题,后续深入学习后在进行讨论. 史上最高性价比PS教程-敬伟Photoshop经典教程

Netty5入门(4)

这个类实现SimpleChannelInboundHandler,SimpleChannelInboundHandler是一个抽象类,实现了中定义的channelRead方法,但同时定义了一个抽象的messageReceived方法,因此我们在MyWebSocketServerHandler类中,不需要实现channelRead方法,但需要实现messageReceived方法.当然,我们还需要覆盖ChannelHandlerAdapter的channelActive方法和channelInac

JAVA通信系列三:Netty入门总结

一.Netty学习资料 书籍<Netty In Action中文版> 对于Netty的十一个疑问http://news.cnblogs.com/n/205413/ 深入浅出Nettyhttp://wenku.baidu.com/view/7765bc2db4daa58da0114a4c.html Netty了解与小试 http://www.cnblogs.com/xd502djj/archive/2012/06/25/2561318.html Netty系列之Netty高性能之道[精彩]htt

OSChina 技术周刊第十五期——每周技术精粹集锦

每周技术抢先看,总有你想要的! 移动开发 [软件]移动基站数据分析 SnoopSnitch [博客]android自动连接wifi--WifiManager [资讯]OSC 安卓客户端全面改版 -- 新界面新体验 [资讯][email protected] 项目推荐 -- Android 日历控件 前端开发 [翻译]JavaScript 应用框架 Bearcat [博客]基于HT的CSG功能构建HTML5的3D书架 [资讯][email protected] 项目推荐 -- AngularJS