概述

具体业务跟下面文章的一样,只是下面文章用的是NIO,这里使用Netty改造。
https://blog.csdn.net/qq_40837310/article/details/111248486

目的是为了熟悉Netty基本API使用。

服务端编码:

public class ServerGroupChatServer {private  int port;public ServerGroupChatServer(int port){this.port = port;}public void start() throws InterruptedException {NioEventLoopGroup bossGroup = new NioEventLoopGroup();NioEventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class)//设置TCP等待队列为128.option(ChannelOption.SO_BACKLOG,128)//长连接.childOption(ChannelOption.SO_KEEPALIVE,true).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception {//添加handlersocketChannel.pipeline().addLast(new MyNettyChannelHandler());}});ChannelFuture bindFuture = serverBootstrap.bind("127.0.0.1", port);//添加一个监听器,监听绑定情况bindFuture.addListener(new GenericFutureListener<Future<? super Void>>() {@Overridepublic void operationComplete(Future<? super Void> future) throws Exception {boolean success = future.isSuccess();if (success)System.out.println("服务绑定成功");else{System.out.println("服务绑定失败");}}});bindFuture.channel().closeFuture().sync();}finally {//关闭bossGroup.shutdownGracefully();//关闭workerGroup.shutdownGracefully();}}public static void main(String[] args) throws InterruptedException {ServerGroupChatServer serverGroupChatServer = new ServerGroupChatServer(9898);serverGroupChatServer.start();}
}

服务端的Handler:

public class MyNettyChannelHandler extends ChannelInboundHandlerAdapter {private static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {//进入这里表示channel已经处于非激活状态,关闭,在这里提示该客户端下线。System.out.println("客户端:" + ctx.channel().remoteAddress() + "已离线");channels.remove(ctx.channel());super.channelInactive(ctx);}//READ事件触发时调用@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {//按照原业务,读取到消息就进行转发for (Channel channel:channels){//排除自身if (channel == ctx.channel())continue;ByteBuf byteBuf = (ByteBuf) msg;byteBuf.retain();//发送channel.writeAndFlush(byteBuf);}ctx.fireChannelRead(msg);}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {//进入这里就证明连接以建立,提醒其他用户此客户端已上线//ChannelGroup的写是里面所有channel 的写channels.writeAndFlush(Unpooled.copiedBuffer("客户端:" + ctx.channel().remoteAddress() + " 已上线。", CharsetUtil.UTF_8));//把当前通道加到集合中channels.add(ctx.channel());super.channelActive(ctx);}//触发异常关闭客户端@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx.fireChannelActive();}
}

客户端代码:

public class NettyGroupChatClient {private  int serverPort;private String clientName;private SocketChannel socketChannel;public NettyGroupChatClient(int serverPort,String clientName){this.clientName = clientName;this.serverPort = serverPort;}public void start() throws InterruptedException {NioEventLoopGroup worker = new NioEventLoopGroup();Bootstrap bootstrap = new Bootstrap();try {bootstrap.group(worker).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel sc) throws Exception {sc.pipeline().addLast(new MyNettyChannelHandlerClient());//sc.pipeline().addLast(new OUT1());//sc.pipeline().addLast(new OUT2());socketChannel = sc;}});ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", serverPort).sync();//添加一个监听器,当连接成功时就给服务端每三秒发送一次数据channelFuture.addListener(new GenericFutureListener<Future<? super Void>>() {@Overridepublic void operationComplete(Future<? super Void> future) throws Exception {if (future.isSuccess()){System.out.println("连接成功");new Thread(()->{while (true) {socketChannel.writeAndFlush(Unpooled.copiedBuffer("Hello, I am " + clientName, CharsetUtil.UTF_8));try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}}}).start();}elseSystem.out.println("连接失败");}});channelFuture.channel().closeFuture().sync();}finally {worker.shutdownGracefully();}}public static void main(String[] args) throws InterruptedException {NettyGroupChatClient Mike = new NettyGroupChatClient(9898,"John");Mike.start();}}

客户端的Handler

public class MyNettyChannelHandlerClient extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf byteBuf = (ByteBuf) msg;System.out.println(byteBuf.toString(CharsetUtil.UTF_8));}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();}
}

运行结果:
客户端1:

客户端2:

客户端3:

都能过接收其他两个客户端发的消息。

把三个客户端关闭后:
服务端控制台:

使用Netty编写一个简单的群聊系统相关推荐

  1. Java NIO 应用案例:实现一个简单的群聊系统

    1 案例要求 编写一个 NIO 多人群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞): 服务器端功能: 监测用户上线,离线: 实现客户端消息的转发功能(将该客户端的消息转发给其它客户端): ...

  2. Netty之实现一个简单的群聊系统

    要求 编写一个 Netty 群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞) 实现多人群聊 服务器端:可以监测用户上线,离线,并实现消息转发功能 客户端:通过channel可以无阻塞发送消息 ...

  3. socket通信 _ 一个简单的群聊系统

    群聊系统要用到通信socket协议,在java中要用到两个类java.net.ServerSocket和 Java.net.Socket.ServerSocket用于创建服务器,而Socket用于创建 ...

  4. 利用Socket实现一个简单的群聊系统

    系统需求 1.实现多个用户即时通信的群聊功能 实现分析 1.当服务端接入一个客户端时,为避免阻塞,并接受其他客户端的接入,为该socket开一个线程管理它. 2.当所接入的客户端中,有客户端发送信息时 ...

  5. (六)Netty网络编程应用实例-群聊系统

    实例要求: 编写一个NIO群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞) 实现多人群聊 服务器端:可以监测用户上线,离线,并实现消息转发功能 客户端:通过channel可以无阻塞发送消息给 ...

  6. php 跳转qq群代码_一个简单QQ群聊案例代码解析(PHP实现)

    问题: 使用面向对象编程的方式实现以下业务逻辑: 1. 张三使用账号a,密码b登录了qq 2. 显示出张三最后的登录的时间 3. 张三查看了 1小时内的行政部门群的信息(这个群里有张三,李四,王五,其 ...

  7. 用C语言编写一个“简单”的程序答题系统

    上个星期我们老师给我们布置一道他认为很简单的题,其实就想考考我们,要我们写一个简单的答题系统.开始一看只有一道题我直呼:"仰天大笑出门去,我辈岂是蓬蒿人" 以为老师放我一马,结果点 ...

  8. 数据库基础,编写一个简单的食堂订餐系统

    这是用jdbc连接数据库,编写食堂的管理系统,是我第一次做的简单项目,只是一次练习,经验不够,代码写的不够好,冗余比较多,欢迎大佬在评论区指出,本人也在不断学习中. 这个项目我写了两天的时间,代码不难 ...

  9. C语言编写一个简单的选择题答题系统

    上个星期,我们老师给我们布置了一道非常变态的作业题.开始一看只有一道题,欣喜若狂, 以为老师终于大发慈悲了一回,结果点开一看,长这样... 顿时就傻了眼,对于一个刚接触C语言一两个月的小白来说,不能说 ...

最新文章

  1. 关于学习Python之后的一点总结(1->符号优先级->for->range())
  2. Swagger2异常:Illegal DefaultValue null for parameter type integer java
  3. 虚拟dom_虚拟DOM发展的前世与今身
  4. Android USB 开发详解
  5. 如何获得物体的主要方向?
  6. java File类入门学习
  7. js(一) 三大事件 实现注册验证
  8. java 中高级面试题_Java中高级面试题
  9. 2021年终总结,我躺平了?
  10. html中文本框角度旋转,如何设置Word文本框旋转,任意角度调整文本框的方向?...
  11. magicbook linux系统换w7,荣耀 MagicBook U盘装系统win7教程
  12. makefile通配符
  13. React-Native强制关闭软键盘
  14. 做的好不如说得好,老板为什么喜欢听过程汇报?
  15. 顶级数学家玩股票胜过巴菲特 被人建议改行(图)
  16. DAY 4 | 自学前端第四天
  17. 最简单的无线充电传输电路
  18. 魅族 -- 禁止D及以下级别LOG的输出
  19. Brain:一种用于阿尔兹海默症(AD)分类的可解释的深度学习框架
  20. Mac上备份iphone照片

热门文章

  1. 如何让CentOS8虚拟机与主机相互Ping通
  2. 利用R和Octave求解线性方程组
  3. 现在时的条件句_57
  4. Horizon8基础环境准备08——CA证书
  5. android 碎片问题,Android碎片问题
  6. Stata和Matlab联合处理金融数据
  7. 歌德语言证书c1考什么,Goethe-Zertifikat C1 (歌德中级证书C1)考试细则 2010.2.1版.pdf...
  8. matlab中ode45函数的用法_带你理解Excel中COUNTIF函数的简单用法
  9. Android:进度条加载
  10. mysql scrapy 重复数据_小心避坑:MySQL分页时使用 limit+order by 会出现数据重复问题...