一.入门
1.前言
NIO跟BIO最大的区别是,NIO有管道(channel)的概念,开启一个管道,传送一批数据,管道里面的Selector充当列车的角色,这个列车来回传输数据。
之所以选用netty,主要原因是因为使用简单,入门快,可以保证在开发的过程中保证项目的稳定以及扩展。
2.入门基础代码
2.1 启动类
首先需要定义一个启动类,netty主要启动代码为
serverBootstrap.group(mainGrp,subGrp)
.channel(NioServerSocketChannel.class)
.childHandler(new WebSocketChanneInit());
这个方法需要三个参数,也是最基本的参数,首先是需要指定现场池,然后是通道的类型,指定完这两个之后需要定义一个通道初始化类,用来加载当通道接收到消息后的业务处理
//创建两个线程池
NioEventLoopGroup mainGrp = new NioEventLoopGroup();
NioEventLoopGroup subGrp = new NioEventLoopGroup();
try {
//创建netty服务器启动对象
ServerBootstrap serverBootstrap = new ServerBootstrap();
//初始化服务启动对象
serverBootstrap.group(mainGrp,subGrp)
.channel(NioServerSocketChannel.class)
.childHandler(new WebSocketChanneInit());
//绑定服务器端口(同步的方式)
ChannelFuture future = serverBootstrap.bind(9001).sync();
//等待服务器关闭
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//关闭
mainGrp.shutdownGracefully();
subGrp.shutdownGracefully();
}
2.2通道初始化器(处理webSocket)
public class WebSocketChanneInit extends ChannelInitializer<SocketChannel> {
//初始化通道
//在这个方法加载对应的channelHandler
protected void initChannel(SocketChannel ch) throws Exception {
//获取管道
ChannelPipeline pipeline = ch.pipeline();
//添加一个http解码器
pipeline.addLast(new HttpServerCodec());
//添加一个用于大数据流的支持
pipeline.addLast(new ChunkedWriteHandler());
//添加一个聚合器
pipeline.addLast(new HttpObjectAggregator(1024 * 64));
//需要指定接收请求的路由,必须使用ws后缀结尾的url才能进行访问
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
//添加自定义的handler
pipeline.addLast(new ChatHandler());
}
}
2.3 自定义Handler(处理业务)
private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
//当接收到数据后会自动调用
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
//获取客服端文本消息
String text = msg.text();
System.out.println("接收到客户端的消息:"+text);
for (Channel client: clients ) {
//将消息发送到所有的客户端
client.writeAndFlush(new TextWebSocketFrame(sdf.format(new Date()) + "接收到消息: "+text ));
}
}
//当有新的客户端连接后会自动调用这个方法
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
//将新的通道放入到clients中
clients.add(ctx.channel());
}