好久没写博客了,2020第一篇博客!
- Netty 我这边就不多加说明了,同步非阻塞典型的NIO架构
- 不过Netty在原有的NIO基础上进行了封装,操作更加简便。
- Selector Channel Buffer 这些组件概念我也不去啰嗦。
- 单Selector 单线程,单Selector多线程,主从Selector多线程 为什么说这一点,因为Netty就是根据主从Selector多线程演变过来的。
我上面这些 这些关键字我这边不做阐述,怕啰嗦…
上代码
- Netty 服务器端
/**
*
* 基于Netty 实现 http 服务器
*/
public class NettyChatServer {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap
.group(bossGroup,workerGroup)
//设置线程连接个数
.option(ChannelOption.SO_BACKLOG,128)
.channel(NioServerSocketChannel.class)
// 连接处于活动状态
.childOption(ChannelOption.SO_KEEPALIVE,true)
.childHandler(new NettyChatInitializer());
ChannelFuture channelFuture = serverBootstrap.bind(6863).sync();
//添加监听器
channelFuture.addListener(future -> {
if (channelFuture.isSuccess()) {
System.out.println("服务器启动成功!连接为:tcp://"+channelFuture.channel().localAddress());
}
});
channelFuture.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
- 服务器端Handler
public class NettyChatInitializer extends ChannelInitializer<SocketChannel> {
//存储该 初始化Channel 用余每次发送群聊消息
public static final List<SocketChannel> socketChannels = new LinkedList<>();
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// ch 类型是 NioSocketChannel
socketChannels.add(ch);
ch.pipeline().addLast(new NettyChatHandler());
}
- Netty服务器端Handler
public class NettyChatHandler extends SimpleChannelInboundHandler<Object> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
//System.out.println("客户端消息为:"+((ByteBuf) msg).toString(CharsetUtil.UTF_8));
String mesStr = ((ByteBuf) msg).toString(CharsetUtil.UTF_8);
// 进行群发路由 这个 channel 就是 NioSocketChannel
Channel channel = ctx.channel();
NettyChatInitializer.socketChannels.forEach(socketChannel -> {
if ( socketChannel instanceof Channel && socketChannel != channel){
socketChannel.writeAndFlush(Unpooled.copiedBuffer(channel.remoteAddress()+": "+mesStr,CharsetUtil.UTF_8));
}
});
/* ByteBuf byteBuf = Unpooled.copiedBuffer("我知道了 我是服务器", CharsetUtil.UTF_8);
ctx.writeAndFlush(byteBuf);*/
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
NettyChatInitializer.socketChannels.remove(ctx.channel());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.err.println("异常产生:"+cause.getMessage());
NettyChatInitializer.socketChannels.remove(ctx.channel());
ctx.close();
}
- 客户端
public class NettyChatClient {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup clientGroups = new NioEventLoopGroup(1);
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(clientGroups)
.channel(NioSocketChannel.class)
.handler(new NettyChatClientInitializer());
ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6863).sync();
channelFuture.addListener(future -> {
if (future.isSuccess()) {
System.out.println("客户端启动成功 " + channelFuture.channel().localAddress());
}
});
channelFuture.channel().closeFuture().sync();
}finally {
clientGroups.shutdownGracefully();
}
}
}
- 客户端Handler
public class NettyChatClientInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new NettyChatClientHandler());
}
- 客户端Handler
public class NettyChatClientHandler extends SimpleChannelInboundHandler<Object> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println(((ByteBuf) msg).toString(CharsetUtil.UTF_8));
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ByteBuf byteBuf = Unpooled.copiedBuffer("我知道了1", CharsetUtil.UTF_8);
ctx.writeAndFlush(byteBuf);
new Thread(()->{
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
ctx.writeAndFlush(Unpooled.copiedBuffer(scanner.nextLine(),CharsetUtil.UTF_8));
}
}).start();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.err.println("异常产生:"+cause.getMessage());
ctx.close();
}
说明:
- 以上代码就是基于Netty的TCP网络编程的范本,学习Netty可以用来参考。