1、Netty是什么?

本质:JBoss做的一个Jar包

目的:快速开发高性能、高可靠性的网络服务器和客户端程序

优点:提供异步的、事件驱动的网络应用程序框架和工具

通俗的说:一个好使的处理Socket的东东

2、Netty的异步事件驱动模型主要涉及到下面几个核心的概念

  Channel:表示一个与socket关联的通道

 ChannelPipeline: 管道,一个Channel拥有一个ChannelPipeline,ChannelPipeline维护着一个处理链(严格的说是两 个:upstream、downstream),处理链是由很        多通道处理器ChannelHandler所构成,每个ChannelHandler处理完以 后会传递给链中的下一个通道处理器继续处理。

ChannelHandler:通道处理器,用户可以定义自己的处理句柄来处理每个请求,或发出请求前进行预处理,典型的有编码/解码器:decoder、encoder。

ChannelEvent:事件,是整个模型的处理对象,当产生或触发(fire)一个事件时,该事件会沿着ChannelPipeline处理链依次被处理。 ChannelFuture: 异步结果,这个是异步事件处理的关键,当一个事件被处理时,可以直接以ChannelFuture的形式直接返回,不用在当前操作中被阻塞。可以通过 ChannelFuture得到最终的执行结果,具体的做法是在ChannelFuture添加监听器listener,当操作最终被执行完 后,listener会被触发,我们可以在listener的回调函数中预定义我们的业务代码。

ChannelPipeline实际上维持了两个处理链:upstream、downstream。 Upstream一般处理来自Channel的读事件,而downstream一般处理向Channel的写事件。需要注意的是,这两个处理链是相互独立 的,在upstream链中传递到最后一个ChannelHandler处理后,不会再传递到downstream链中继续处理。

downstream链的末端会有个ChannelSink处理,用户可以自定义这个ChannelSink的实现,系统也有个默认的实现,当downstream链中最后一个ChannelHandler处理完后会被传递给这个ChannelSink进行最后的处理。

3、Demo

3.1、NettyServer.java

package com.jacky.server;

import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler; public class NettyServer { private static Logger logger = Logger.getLogger(NettyServer.class);
private int port;
public NettyServer(int port) {
this.port = port;
bind();
} private void bind() { EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(boss, worker);
bootstrap.channel(NioServerSocketChannel.class);
bootstrap.option(ChannelOption.SO_BACKLOG, 1024); //连接数
bootstrap.option(ChannelOption.TCP_NODELAY, true); //不延迟,消息立即发送
bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); //长连接
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel)
throws Exception {
ChannelPipeline p = socketChannel.pipeline();
p.addLast(new NettyServerHandler());
}
});
ChannelFuture f = bootstrap.bind(port).sync();
if (f.isSuccess()) {
logger.debug("启动Netty服务成功,端口号:" + this.port);
}
// 关闭连接
f.channel().closeFuture().sync(); } catch (Exception e) {
logger.error("启动Netty服务异常,异常信息:" + e.getMessage());
e.printStackTrace();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
} public static void main(String[] args) throws InterruptedException { NettyServer server= new NettyServer(9999); } }

3.2、NettyServerHandler.java

      

package com.jacky.server;

import java.io.UnsupportedEncodingException;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext; public class NettyServerHandler extends ChannelHandlerAdapter { @Override
public void channelRead(ChannelHandlerContext context, Object msg) {
ByteBuf buf = (ByteBuf) msg;
String recieved = getMessage(buf);
System.out.println("服务器接收到消息:" + recieved);
try {
context.writeAndFlush(getSendByteBuf("APPLE"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} /*
* 从ByteBuf中获取信息 使用UTF-8编码返回
*/
private String getMessage(ByteBuf buf) { byte[] con = new byte[buf.readableBytes()];
buf.readBytes(con);
try {
return new String(con, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
} private ByteBuf getSendByteBuf(String message)
throws UnsupportedEncodingException { byte[] req = message.getBytes("UTF-8");
ByteBuf pingMessage = Unpooled.buffer();
pingMessage.writeBytes(req); return pingMessage;
}
}

 3.3、NettyClient.java

   

package com.jacky.client;

import java.util.concurrent.TimeUnit;

import io.netty.bootstrap.Bootstrap;
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;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.timeout.IdleStateHandler; public class NettyClient { /*
* 服务器端口号
*/
private int port; /*
* 服务器IP
*/
private String host; public NettyClient(int port, String host)
throws InterruptedException {
this.port = port;
this.host = host;
start();
} private void start() throws InterruptedException { EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap();
bootstrap.channel(NioSocketChannel.class);
bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
bootstrap.group(eventLoopGroup);
bootstrap.remoteAddress(host, port);
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel)
throws Exception {
socketChannel.pipeline().addLast(new NettyClientHandler());
}
});
ChannelFuture future = bootstrap.connect(host, port).sync();
if (future.isSuccess()) {
SocketChannel socketChannel = (SocketChannel) future.channel();
System.out.println("----------------connect server success----------------");
}
future.channel().closeFuture().sync();
} finally {
eventLoopGroup.shutdownGracefully();
}
} public static void main(String[] args) throws InterruptedException { NettyClient client = new NettyClient(9999, "localhost"); }
}

3.4、NettyClientHandler.java

  

package com.jacky.client;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
public class NettyClientHandler extends ChannelHandlerAdapter {
private ByteBuf firstMessage;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
byte[] data = "服务器,给我一个APPLE".getBytes();
firstMessage=Unpooled.buffer();
firstMessage.writeBytes(data);
ctx.writeAndFlush(firstMessage);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
ByteBuf buf = (ByteBuf) msg;
String rev = getMessage(buf);
System.out.println("客户端收到服务器数据:" + rev);
}
private String getMessage(ByteBuf buf) {
byte[] con = new byte[buf.readableBytes()];
buf.readBytes(con);
try {
return new String(con, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}

最新文章

  1. RequireJS学习笔记
  2. boost库的使用
  3. 十天冲刺---Day9
  4. 【linux】设置 tomcat 开机启动
  5. Substring的简单使用
  6. mac 软件安装
  7. Js验证 :只能输入数字和小数点 验证是否是数字 js取float型小数点后两位
  8. hdu 1208 Pascal&#39;s Travels
  9. android如何使用自己定义JNI接口,以及NDK环境建设和使用的工具。
  10. hdu 1213 How Many Tables(并查集练习)
  11. Servlet中Response对象应用1(输出简单文字、实现文件下载)
  12. [转].NET程序破解仅需三步
  13. i++是否原子操作?并解释为什么???????
  14. 一HTML基础知识
  15. Maven学习笔记2(坐标和依赖)
  16. build.gradle文件的注释
  17. zabbix3.0 安装时出现PHP Parse error: syntax error
  18. MySql与SqlServer的区别
  19. 【坚持】Selenium+Python学习记录 DAY9
  20. Tomcat不自动解压问题

热门文章

  1. 使用Elasticsearch 与 NEST 库 构建 .NET 企业级搜索
  2. Android API之android.provider.ContactsContract.RawContacts
  3. 微信小程序之分享,动态添加分享数据
  4. Python 的 if __name__ == &#39;__main__&#39;
  5. Android的各版本间的区别总结
  6. iOS - 跑马灯、弹幕
  7. 【ERROR】Oracle11g两个监听同名进程的故障
  8. python os库学习笔记
  9. PLSQL_SQL Loader的概念和用法(概念)
  10. BIP_BI Pubisher的SQL/XSL/FO扩展函数应用(概念)