官网
https://netty.io/
Netty is an asynchronous event-driven network application framework
for rapid development of maintainable high performance protocol servers & clients.
Netty是一个异步的、基于事件驱动的网络应用框架,用于快速开发可维护、高性能的网络服务器和客户端。
客户端发送,服务端接收案例
// 服务端
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ServerDemo {
private static final Logger log = LoggerFactory.getLogger(ServerDemo.class);
public static void main(String[] args) {
// 启动服务器
new ServerBootstrap()
// 设置线程组
.group(new NioEventLoopGroup())
// ServerSocketChannel模式选择
.channel(NioServerSocketChannel.class)
// worker处理连接
.childHandler(
// 通道初始化,添加handler
new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
// 将buffer转为字符串
nioSocketChannel.pipeline().addLast(new StringDecoder());
// 自定义处理器
nioSocketChannel.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx,Object msg)throws Exception {
log.info(msg.toString());
}
});
}
})
// 绑定端口
.bind(8090);
}
}
// 客户端
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
public class ClientDemo {
public static void main(String[] args) throws InterruptedException {
// 启动类
new Bootstrap()
// 添加eventloop
.group(new NioEventLoopGroup())
// 选择客户端实现
.channel(NioSocketChannel.class)
// 添加处理器
.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
nioSocketChannel.pipeline().addLast(new StringEncoder());
}
})
// 连接到服务器
.connect("localhost",8090)
// 阻塞方法,直到连接建立
.sync()
// 获取连接对象
.channel()
// 向服务器发送数据
.writeAndFlush("微信小程序:马上行计划管理,欢迎体验。");
}
}
客户端调试idea设置
允许启动多实例
启用多线程调试,断点处右键
netty常用组件
EventLoop
本质是一个单线程执行器维护了一个Selector,管理channel。
public interface EventLoop extends OrderedEventExecutor, EventLoopGroup
Channel
建立连接后channel与EventLoop绑定。
Future和Promise
@Test
public void testJdkFeature() throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<Integer> submit = executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
log.info("Callable");
Thread.sleep(1000);
return 10;
}
});
log.info("执行完成submit");
log.info("等待结果{}", submit.get());
}
@Test
public void testNettyFeature() throws Exception {
NioEventLoopGroup group = new NioEventLoopGroup();
try {
EventLoop next = group.next();
io.netty.util.concurrent.Future<Integer> future = next.submit(() -> {
log.info("Callable");
Thread.sleep(1000);
return 20;
});
// 使用CountDownLatch等待异步操作完成
CountDownLatch latch = new CountDownLatch(1);
future.addListener((GenericFutureListener<io.netty.util.concurrent.Future<? super Integer>>) f -> {
try {
log.info("等待结果{}", f.getNow());
} finally {
latch.countDown();
}
});
log.info("执行完成submit");
// 等待异步操作完成,设置合理的超时时间
assertTrue(latch.await(2, TimeUnit.SECONDS));
} finally {
group.shutdownGracefully().sync();
}
}
@Test
public void testNettyPromise() throws Exception{
EventLoop next = new NioEventLoopGroup().next();
DefaultPromise<Integer> promise = new DefaultPromise<>(next);
new Thread(()->{
log.info("新线程开始");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
promise.setSuccess(30);
}).start();
log.debug("等待结束");
// 等待异步操作完成,设置合理的超时时间
log.info("计算结果是{}",promise.get());
}
Handler和Pipline
Pipline相当于一个流水线,而Handler则相当于流水线每一个工序。
Hander分为入站和出栈两种类型。
pipline执行handler数序
public class PiplineDemo {
static final Logger log = LoggerFactory.getLogger(PiplineDemo.class);
public static void main(String[] args) {
// 启动服务器
new ServerBootstrap()
// 设置线程组
.group(new NioEventLoopGroup(),new NioEventLoopGroup())
// ServerSocketChannel模式选择
.channel(NioServerSocketChannel.class)
// worker处理连接,一个channel绑定一个eventloop
.childHandler(
// 通道初始化,添加handler
new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
ChannelPipeline pipeline = nioSocketChannel.pipeline();
// 处理器head->first->second->third->sixth->fifth->fourth->tail
pipeline.addLast("first",new ChannelInboundHandlerAdapter(){
public void channelRead(ChannelHandlerContext ctx,Object message) throws Exception {
log.info("first");
super.channelRead(ctx,message);
}
});
pipeline.addLast("second",new ChannelInboundHandlerAdapter(){
public void channelRead(ChannelHandlerContext ctx,Object message) throws Exception {
log.info("second");
super.channelRead(ctx,message);
}
});
pipeline.addLast("third",new ChannelInboundHandlerAdapter(){
public void channelRead(ChannelHandlerContext ctx,Object message) throws Exception {
log.info("third");
// super.channelRead(ctx,message);
// 使用nioSocketChannel从tail往前走所有的出站处理器
// nioSocketChannel.writeAndFlush(ctx.alloc().buffer().writeBytes("欢迎使用微信小程序马上行计划管理".getBytes()));
// 使用ctx从当前位置往前找出站处理器
ctx.writeAndFlush(ctx.alloc().buffer().writeBytes("欢迎使用微信小程序马上行计划管理".getBytes()));
}
});
pipeline.addLast("fourth",new ChannelOutboundHandlerAdapter(){
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
log.info("fourth");
super.write(ctx,msg,promise);
}
});
pipeline.addLast("fifth",new ChannelOutboundHandlerAdapter(){
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
log.info("fifth");
super.write(ctx,msg,promise);
}
});
pipeline.addLast("sixth",new ChannelOutboundHandlerAdapter(){
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
log.info("sixth");
super.write(ctx,msg,promise);
}
});
}
})
// 绑定端口
.bind(8090);
}
}
测试handler及顺序
private static final Logger log = LoggerFactory.getLogger(ClientDemo.class);
public static void main(String[] args) {
ChannelInboundHandlerAdapter first=new ChannelInboundHandlerAdapter(){
public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
log.info("first");
super.channelRead(ctx,message);
}
};
ChannelInboundHandlerAdapter second=new ChannelInboundHandlerAdapter(){
public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
log.info("second");
super.channelRead(ctx,message);
}
};
ChannelOutboundHandlerAdapter fourth=new ChannelOutboundHandlerAdapter(){
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
log.info("fourth");
super.write(ctx,msg,promise);
}
};
ChannelOutboundHandlerAdapter fifth=new ChannelOutboundHandlerAdapter(){
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
log.info("fifth");
super.write(ctx,msg,promise);
}
};
EmbeddedChannel channel = new EmbeddedChannel(first,second,fourth,fifth);
// 模拟入栈
channel.writeInbound("欢迎使用微信小程序马上行计划管理".getBytes());
// 模拟出站
channel.writeOutbound("欢迎使用微信小程序马上行计划管理".getBytes());
}
ByteBuf
自动扩容,内存管理使用引用计数器法。
// 堆内存
ByteBufAllocator.DEFAULT.heapBuffer();
// 直接内存
ByteBufAllocator.DEFAULT.directBuffer();
此文技术,助力微信小程序:马上行计划管理。
欢迎体验,微信搜索马上行计划管理,或者扫码