netty简单入门:
netty版本大致版本分为 netty3.x 和 netty4.x、netty5.x
netty可以运用在那些领域?
1分布式进程通信
例如: hadoop、dubbo、akka等具有分布式功能的框架,底层RPC通信都是基于netty实现的,这些框架使用的版本通常都还在用netty3.x
2、游戏服务器开发
最新的游戏服务器有部分公司可能已经开始采用netty4.x 或 netty5.x
1、netty服务端hello world案例
创建一个maven项目使用的pom依赖是
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.21.Final</version>
</dependency>
SimpleChannelHandler 处理消息接收和写
- messageReceived接收消息
- channelConnected新连接,通常用来检测IP是否是黑名单
- channelDisconnected链接关闭,可以再用户断线的时候清楚用户的缓存数据等
2、netty客户端hello world案例
channelDisconnected与channelClosed的区别?
channelDisconnected只有在连接建立后断开才会调用 channelClosed无论连接是否成功都会调用关闭资源
下面看使用netty实现服务器端Server和客户端Client小栗子:
Server:
public class Server {
public static void main(String[] args) {
//创建一个服务类
ServerBootstrap serverBootstrap = new ServerBootstrap();
//创建2个线程池分别负责监听端口和处理通道读写任务
ExecutorService boss = Executors.newCachedThreadPool();
ExecutorService work = Executors.newCachedThreadPool();
//设置Nio工厂
serverBootstrap.setFactory(new NioServerSocketChannelFactory(boss,work));
//设置管道工厂
serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder",new StringDecoder());
pipeline.addLast("encoder",new StringEncoder());
pipeline.addLast("hellhandler",new HelloHandler());
return pipeline;
}
});
serverBootstrap.bind(new InetSocketAddress(10010));
System.out.println("服务器启动...");
}
}
Client:
public class Client {
public static void main(String[] args) {
//客户端服务类
ClientBootstrap bootstrap = new ClientBootstrap();
ExecutorService boss = Executors.newCachedThreadPool();
ExecutorService work = Executors.newCachedThreadPool();
bootstrap.setFactory(new NioClientSocketChannelFactory(boss,work));
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder",new org.jboss.netty.handler.codec.string.StringDecoder());
pipeline.addLast("encoder",new org.jboss.netty.handler.codec.string.StringEncoder());
pipeline.addLast("hihandler",new HiHandler());
return pipeline;
}
});
ChannelFuture channelFuture = bootstrap.connect(new InetSocketAddress("192.168.213.1",10010));
System.out.println("Client start...");
Channel channel = channelFuture.getChannel();
Scanner scanner = new Scanner(System.in);
while(true){
System.out.println("请输入");
if(channel.isWritable()) {
channel.write(scanner.next());
}
}
}
}
HelloHandler和HiHandler代码一样:
public class HelloHandler extends SimpleChannelHandler {
/**
* 接受消息
* @param ctx
* @param e
* @throws Exception
*/
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
String s = (String)e.getMessage();
System.out.println(s);
//回写数据
if(ctx.getChannel().isWritable()) {
ctx.getChannel().write("hi");
super.messageReceived(ctx, e);
}
}
/**
* 捕获异常
* @param ctx
* @param e
* @throws Exception
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
System.out.println("exceptionCaught");
ctx.getChannel().close();
System.out.println("连接关闭");
//super.exceptionCaught(ctx, e);
}
/**
* 新的连接进来
* @param ctx
* @param e
* @throws Exception
*/
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelConnected");
super.channelConnected(ctx, e);
}
/**
* 连接已经建立后,通道断开连接
* @param ctx
* @param e
* @throws Exception
*/
@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelDisconnected");
super.channelDisconnected(ctx, e);
}
/**
* 连接断开(包含了连接不上的情况)
* @param ctx
* @param e
* @throws Exception
*/
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
System.out.println("channelClosed");
super.channelClosed(ctx, e);
}
}
运行便可实现一个简单的聊天室的功能。
代码地址:项目git地址