Netty的群发实现2
来源:互联网 发布:朝鲜脱北者 知乎 编辑:程序博客网 时间:2024/06/08 23:06
下面代码需要talent 进行模拟客户端。采用的是netty4.1.16 JDK1.8
我用的Xshell一样可以实现
具体代码实现如下
package qunfa;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelOption;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;public class NettyServer { public void bing(int port) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workGroup); b.channel(NioServerSocketChannel.class); b.option(ChannelOption.SO_BACKLOG, 1024); b.childHandler(new ChildChannelHandler()); // 绑定端口 ChannelFuture f = b.bind(port).sync(); // 等待服务端监听端口关闭 f.channel().closeFuture().sync(); } finally { // 优雅的退出 bossGroup.shutdownGracefully(); workGroup.shutdownGracefully(); } } public static void main(String[] args) { try { System.out.println("服务端开启等待客户端链接"); new NettyServer().bing(2333); } catch (Exception e) { e.printStackTrace(); } }}
package qunfa;import io.netty.channel.ChannelInitializer;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.LineBasedFrameDecoder;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;public class ChildChannelHandler extends ChannelInitializer<SocketChannel> { @Override protected void initChannel(SocketChannel e) throws Exception { System.out.println("报告"); System.out.println("信息:有一客户端链接到本服务端"); System.out.println("IP:" + e.localAddress().getHostName()); System.out.println("Port:" + e.localAddress().getPort()); System.out.println("报告完毕"); // 解码器 // 以"\n"或者"\r\n"作为分隔符,解决粘包和半包问题 e.pipeline().addLast(new LineBasedFrameDecoder(1024)); // 基于指定字符串【换行符,这样功能等同于LineBasedFrameDecoder,以/r/n或者/n作为分隔符】 //e.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, false, Delimiters.lineDelimiter())); // 基于最大长度 //e.pipeline().addLast(new FixedLengthFrameDecoder(4)); e.pipeline().addLast(new StringDecoder()); e.pipeline().addLast(new StringEncoder()); e.pipeline().addLast(new MyServerHanlder()); }}
package qunfa;import io.netty.channel.group.ChannelGroup;import io.netty.channel.group.DefaultChannelGroup;import io.netty.util.concurrent.GlobalEventExecutor;/** * * 这里讲ChannelGroup单独放到一个类里,并有多个客户端使用 * 同时ChannelGroup是static的 * 说明:这不是唯一的处理方式 * */public class MyChannelHandlerPool { public static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);}
package qunfa;import java.util.Date;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;//public class MyServerHanlder extends ChannelHandlerAdapter{public class MyServerHanlder extends ChannelInboundHandlerAdapter{ /* * channelAction * * channel 通道 * action 活跃的 * * 当客户端主动链接服务端的链接后,这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据 * */ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println(ctx.channel().localAddress().toString() + " channelActive"); //添加到channelGroup 通道组 MyChannelHandlerPool.channelGroup.add(ctx.channel()); //通知已经链接上客户端 回写数据 String str = "您已经开启与服务端链接" + " " + ctx.channel().id() + new Date() + " " + ctx.channel().localAddress(); ctx.writeAndFlush(str); } /* * channelInactive * * channel 通道 * Inactive 不活跃的 * * 当客户端主动断开服务端的链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据 * */ @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { // 从channelGroup中移除,当有客户端退出后,移除channel。 MyChannelHandlerPool.channelGroup.remove(ctx.channel()); System.out.println(ctx.channel().localAddress().toString() + " channelInactive"); } /* * channelRead * * channel 通道 * Read 读 * * 简而言之就是从通道中读取数据,也就是服务端接收客户端发来的数据 * 但是这个数据在不进行解码时它是ByteBuf类型的后面例子我们在介绍 * */ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //注意此处已经不需要手工解码了,将信息显示在控制台 System.out.println(ctx.channel().id() + "" + new Date() + " " + msg); //通知您已经链接上客户端[给客户端穿回去的数据加个换行] String str = "服务端收到:" + ctx.channel().id() + new Date() + " " + msg + "\r\n"; //收到信息后,群发给所有小伙伴 MyChannelHandlerPool.channelGroup.writeAndFlush(str); } /* * channelReadComplete * * channel 通道 * Read 读取 * Complete 完成 * * 在通道读取完成后会在这个方法里通知,对应可以做刷新操作 * ctx.flush() * */ @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } /* * exceptionCaught * * exception异常 * Caught抓住 * * 抓住异常,当发生异常的时候,可以做一些相应的处理,比如打印日志、关闭链接 * */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); System.out.println("异常信息:\r\n"+cause.getMessage()); }}
阅读全文
0 0
- Netty的群发实现2
- Netty下的消息群发
- Netty 群发信息
- 群发“站内信”的实现
- 群发站内信的实现
- 群发“站内信”的实现
- 群发“站内信”的实现
- 群发“站内信”的实现
- netty的简单实现
- 群发邮件的实现(没代码)
- MFC 实现网络消息的群发
- Delphi7中群发电子邮件的实现
- 网站系统 群发“站内信”的实现
- 关于短信群发的简单实现
- netty的心跳检测实现
- netty的心跳检测实现
- netty 对 http 的实现
- 利用客服消息和模板消息实现微信群发(突破群发接口的上限)
- python操作xls、xlsx格式Excel笔记
- JAVASE之权限修饰内部类
- 416. Partition Equal Subset Sum
- Leetcode7. Reverse Integer
- 浅析Java中HashMap的底层原理
- Netty的群发实现2
- 第一次CCF CSP认证体验
- spring boot 自定义配置文件的类型转换
- Unity Android 加载动态库
- 大数据WEB阶段 (十)Response、ServletConfig、ServletContext、资源跳转三种方式
- jQuery学习笔记(四)封装js框架
- Excel和CSV格式文件的不同之处
- IETF/RFC--TCP/IP/Ethernet--IP分片
- C6748_NMI