主程序启动模版
package net.jlxxw.wechat.temp;
import io.netty.bootstrap.ServerBootstrap;
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.NioServerSocketChannel;
import net.jlxxw.wechat.component.netty.WeChatCoreComponent;
import net.jlxxw.wechat.util.LoggerUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
private static final ServerBootstrap BOOTSTRAP = new ServerBootstrap();
private static final Logger logger = LoggerFactory.getLogger(WeChatCoreComponent.class);
public static void main(String[] args) {
LoggerUtils.info(logger, "初始化 netty 组件");
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workGroup = new NioEventLoopGroup(200);
BOOTSTRAP
.group(bossGroup, workGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast("channel_manager",new AllChannelManager());
socketChannel.pipeline().addLast("chatChannel", new ChatChannel());
LoggerUtils.debug(logger, "初始化 netty 微信协议处理器 成功");
}
})
.localAddress(9999)
.option(ChannelOption.SO_BACKLOG, 200)
.childOption(ChannelOption.SO_KEEPALIVE, false);
try {
ChannelFuture future = BOOTSTRAP.bind(9999).sync();
LoggerUtils.info(logger, "netty服务启动,开始监听端口: {}", 9999);
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
LoggerUtils.error(logger, "netty服务启动失败!!!", e);
System.exit(0);
} finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}
业务处理channel
package net.jlxxw.wechat.temp;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import net.jlxxw.wechat.util.LoggerUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
@Component
@ChannelHandler.Sharable
public class ChatChannel extends SimpleChannelInboundHandler<ByteBuf> {
private static final Logger logger = LoggerFactory.getLogger(ChatChannel.class);
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
LoggerUtils.debug(logger, "netty 开始处理");
byte[] reqContent = new byte[byteBuf.readableBytes()];
byteBuf.readBytes(reqContent);
final String requestData = new String(reqContent, StandardCharsets.UTF_8);
logger.info("接收到请求数据:{}",requestData);
AllChannelManager.sendAll(requestData);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
LoggerUtils.error(logger,"netty-thread 发生未知异常",cause);
ctx.close();
}
}
channel管理器
package net.jlxxw.wechat.temp;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.ImmediateEventExecutor;
public class AllChannelManager extends ChannelDuplexHandler {
private final static ChannelGroup CHANNEL_GROUP = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
CHANNEL_GROUP.add(ctx.channel());
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
CHANNEL_GROUP.remove(ctx.channel());
super.channelInactive(ctx);
}
public static void sendAll(String message){
CHANNEL_GROUP
.parallelStream()
.filter(Channel::isActive)
.forEach(channel -> {
ByteBuf byteBuf = Unpooled.directBuffer(message.length());
byteBuf.writeCharSequence(message, CharsetUtil.UTF_8);
channel.writeAndFlush(byteBuf);
});
}
}