Netty小案例
2021-01-18 14:12
标签:适配 public override 读取 info 如图所示 extends connect syn Netty是基于主从Reactor模型的 BossGroup只关系Accpet(连接的建立) 维护selector 接收到Accpet事件后 获取到对应的SocketChannel 并封装成NIOSocketChannel并注册到Worker,进行维护,当Woker监听到selector 中通道发生感兴趣的事情 就由handler进行处理 (handler需要先添加进通道中)模型如图所示: NettyClient: Netty小案例 标签:适配 public override 读取 info 如图所示 extends connect syn 原文地址:https://www.cnblogs.com/mc-74120/p/13342933.htmlpublic class NettyClient {
public static void main(String[] args) throws InterruptedException {
//客户端需要一个事件循环组
NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup();
try{
//创建客户端启动对象
Bootstrap bootstrap = new Bootstrap();
//设置相关参数
bootstrap.group(nioEventLoopGroup)
.channel(NioSocketChannel.class).
handler(new ChannelInitializer
@Override
protected void initChannel(SocketChannel channel) throws Exception {
channel.pipeline().addLast(new NettyClientHandler());
}
});
System.out.println("客户端准备好了");
//启动客户端去连接服务器端
ChannelFuture cf = bootstrap.connect("127.0.0.1", 8848).sync();
cf.channel().closeFuture().sync();
}finally {
nioEventLoopGroup.shutdownGracefully();
}
}
}
ClentHandler:public class NettyClientHandler extends ChannelInboundHandlerAdapter {
//通道就绪触发该方法
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
ctx.writeAndFlush(Unpooled.copiedBuffer("hello,123", CharsetUtil.UTF_8));
}
//当通道有读取事件时
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf byteBuf= (ByteBuf) msg;
System.out.println(byteBuf.toString(CharsetUtil.UTF_8));
System.out.println(ctx.channel().remoteAddress());
}
@Override
//处理异常 一般需要关闭通道
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.channel().close();
}
}
Server:public class NettyServer {
public static void main(String[] args) throws InterruptedException {
//创建BossGroup和WorkerGroup
//bossGroup处理连接请求 workerGroup处理业务
//底层都是无限循环
EventLoopGroup boosGroup = new NioEventLoopGroup();
EventLoopGroup workerGruop = new NioEventLoopGroup();
try{
//服务器端启动对象 配置参数
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(boosGroup,workerGruop)//设置两个线程组
.channel(NioServerSocketChannel.class)//设置通道类型
.option(ChannelOption.SO_BACKLOG,128)//设置线程队列的连接个数
.childOption(ChannelOption.SO_KEEPALIVE,true)//设置保持活动状态
.childHandler(new ChannelInitializer
//给pipeline设置处理器
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new NettyServerHandler());
}
});//给workerGroup的EventLoop对应的管道设置处理器
System.out.println("服务器准备好了");
//绑定端口并启动服务器
ChannelFuture channelFuture = serverBootstrap.bind(8848).sync();
//对通道关闭进行监听
channelFuture.channel().closeFuture().sync();
}
finally {
boosGroup.shutdownGracefully();
workerGruop.shutdownGracefully();
}
}
}
ServerHandler://自定义的handler需要实现netty规定的某个适配器 自定义的handler才能称为handler
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
//读取客户端发送的消息
/*
ChannelHandlerContext上下文对象 含有通道 管道 地址等
Object msg 客户端发送的数据
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf byteBuf=(ByteBuf)msg;
System.out.println(byteBuf.toString(CharsetUtil.UTF_8));
System.out.println(ctx.channel().remoteAddress());
}
//数据读取完毕
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
//数据写入缓冲并刷新
//数据需要编码并发送
ctx.writeAndFlush(Unpooled.copiedBuffer("hello",CharsetUtil.UTF_8));
}
@Override
//处理异常 一般需要关闭通道
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.channel().close();
}
}
上一篇:什么是HTML语义化?
下一篇:《PHP PSR 标准规范》