使用Netty实现群发消息
- netty简单介绍
- 实现群发流程图
- 代码实现
- NettyServer 类
- MyChannelInitializer 类
- MyServerHandler 类
- ChannelHandler 类
- Netty 依赖
- 效果展示
- netAssist 工具
- 启动Netty server
- 打开netAssist 工具
netty简单介绍
Netty是由JBOSS提供的一个java开源框架,Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
今天我们简单的使用Netty 来实现下群发功能.
实现群发流程图
流程图比较详细。看图应该就差不多了。不清楚的,后面有详细代码粘贴。
代码实现
NettyServer 类
public static void main(String[] args) {
try {
new NettyServer().bind(8080);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void bind(int port) throws InterruptedException {
//配置服务端线程组
EventLoopGroup parentGroup=new NioEventLoopGroup();
EventLoopGroup childGroup=new NioEventLoopGroup();
ServerBootstrap bootstrap=new ServerBootstrap();
bootstrap.group(parentGroup,childGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG,128)
//配置初始化Channel类
.childHandler(new MyChannelInitializer());
ChannelFuture future=bootstrap.bind(port).sync();
System.out.println("echo test.........66666");
future.channel().closeFuture().sync();
}
MyChannelInitializer 类
public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {
protected void initChannel(SocketChannel channel) throws Exception {
//解码器
//基于换行符号
channel.pipeline().addLast(new LineBasedFrameDecoder(1024));
//基于指定字符串(换行符),这样功能和LineBaseFrameDecoder的功能类似
//解码转String,注意调整自己的编码格式
channel.pipeline().addLast(new StringDecoder(Charset.forName("GBK")));
//编码格式
channel.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));
//在管道中添加我们自己的接收数据实现方法
channel.pipeline().addLast(new MyServerHandler());
}
}
MyServerHandler 类
public class MyServerHandler extends ChannelInboundHandlerAdapter {
private SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD HH:mm:ss");
@Override
public void channelRead(ChannelHandlerContext channelHandlerContext, Object obj) throws UnsupportedEncodingException {
System.out.println(sdf.format(new Date()) + "\n" + obj);
//接收数据
String str = "服务端接收到了消息:" + sdf.format(new Date());
//通知客户端
//ByteBuf buf = Unpooled.buffer(str.getBytes().length);
//buf.writeBytes(str.getBytes("GBK"));
//channelHandlerContext.writeAndFlush(str);
ChannelHandler.channels.writeAndFlush(str);
}
@Override
public void channelActive(ChannelHandlerContext channelHandlerContext) throws IOException {
//当有客户端连接时,将其添加到channelGroup中
ChannelHandler.channels.add(channelHandlerContext.channel());
NioSocketChannel channel = (NioSocketChannel) channelHandlerContext.channel();
System.out.println("链接报告开始 {公众号:bugstack虫洞栈 >获取学习源码}");
System.out.println("链接报告信息:有一客户端链接到本服务端");
System.out.println("链接报告IP:" + channel.localAddress().getHostName());
System.out.println("链接报告Port:" + channel.localAddress().getPort());
System.out.println("链接报告完毕");
//通知客户端连接成功
String dateStr = sdf.format(new Date());
String str = "通知客户端建立连接成功...." + dateStr + channel.localAddress();
//ByteBuf buf = Unpooled.buffer(str.getBytes().length);
// buf.writeBytes(str.getBytes("GBK"));
ChannelHandler.channels.writeAndFlush(str);
}
@Override
public void channelInactive(ChannelHandlerContext context) {
System.out.println("断开连接...." + context.channel().localAddress());
//当有客户端断开连接时,将其从channelGroup中移除
ChannelHandler.channels.remove(context.channel());
}
@Override
public void exceptionCaught(ChannelHandlerContext channelHandlerContext,Throwable throwable){
channelHandlerContext.close();
System.out.println("异常信息: \n"+throwable);
}
}
ChannelHandler 类
public class ChannelHandler {
public static ChannelGroup channels=
new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
}
Netty 依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.36.Final</version>
</dependency>
效果展示
netAssist 工具
下载地址:
https://download.csdn.net/download/echohuangshihuxue/87311946?spm=1001.2014.3001.5503
启动Netty server
启动NettyServer 的main方法即可启动 Netty 服务端。同时 会监控客户端的连接。
打开netAssist 工具
利用netAssist 来模拟客户端的连接。
具体的逻辑是MyServerHandler 类。可以参考流程图和代码进行理解和联系。如有疑问,欢迎评论。