1 需求

(1) 编写一个 Netty群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞)
(2) 实现多人群聊
(3) 服务器端:可以监测用户上线,离线,并实现消息转发功能
(4) 客户端:通过 channel可以无阻塞发送消息给其它所有用户,同时可以接受其它用
(5) 户发送的消息(有服务器转发得到)
目的:进一步理解Net非阻塞网络编程机制

2 Code

2.1 GroupChatConsts

public final class GroupChatConsts {private GroupChatConsts() {}public static final Integer port = 8888;public static final String host = "127.0.0.1";}

2.2 GroupChatServer

(1) GroupChatServerHandler

package com.rosh.netty.chat.server;import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;import java.text.SimpleDateFormat;
import java.util.Date;/*** @Description:* @Author: rosh* @Date: 2020/12/29 22:59*/
public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {/*** 定义一个channel组,管理所有的channel*/private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");/*** 当建立连接时,第一个被执行*/@Overridepublic void handlerAdded(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();//通知其他客户,有人加入该聊天室channelGroup.writeAndFlush("【客户端】 " + sdf.format(new Date()) + channel.remoteAddress() + " 加入聊天 \n");//加入聊天channelGroup.add(channel);}/*** 表示channel处于一个活跃的状态*/@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println("【" + ctx.channel().remoteAddress() + "】 " + sdf.format(new Date()) + " 上线了 ~");}/***  表示channel处于不活动的状态*/@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {System.out.println("【" + ctx.channel().remoteAddress() + "】 " + sdf.format(new Date()) + " 离线了 ~");}/*** channel断开连接会被触发*/@Overridepublic void handlerRemoved(ChannelHandlerContext ctx) throws Exception {Channel channel = ctx.channel();channelGroup.writeAndFlush("【客户端】 " + sdf.format(new Date()) + channel.remoteAddress() + " 离开了\n");}/*** 转发消息*/@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {Channel channel = ctx.channel();channelGroup.forEach(ch -> {if (channel != ch) {ch.writeAndFlush("【客户】" + sdf.format(new Date()) + channel.remoteAddress() + "发送了消息: " + msg + "\n");} else {ch.writeAndFlush("【自己】" + sdf.format(new Date()) + "发送了消息: " + msg + "\n");}});}/*** 发生异常时 关闭通道*/@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx.close();}
}

(2) GroupChatServerChannelInitializer

public class GroupChatServerChannelInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();//解码器pipeline.addLast("decoder", new StringDecoder());//编码器pipeline.addLast("encoder", new StringEncoder());//加入自己业务handlerpipeline.addLast("serverHandler", new GroupChatServerHandler());}
}

(3) GroupChatServerHandler

public class GroupChatServer {public static void main(String[] args) {NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);NioEventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossGroup, workerGroup)//nio.channel(NioServerSocketChannel.class)//bossGroup,option,服务端接受连接的队列长度,如果队列已满,客户端连接将被拒绝。.option(ChannelOption.SO_BACKLOG, 128)//workerGroup,option,是否启动心跳包活机制.childOption(ChannelOption.SO_KEEPALIVE, true).childHandler(new GroupChatServerChannelInitializer());//绑定端口ChannelFuture channelFuture = serverBootstrap.bind(GroupChatConsts.port).sync();//监听关闭事件channelFuture.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}}

2.3 GroupChatClient

(1) GroupChatClientHandler

public class GroupChatClientHandler extends SimpleChannelInboundHandler<String> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {System.out.println(msg.trim());}
}

(2) GroupChatClientChannelInitializetr

public class GroupChatClientChannelInitializetr  extends ChannelInitializer<SocketChannel>{@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();//解码器pipeline.addLast("decoder", new StringDecoder());//编码器pipeline.addLast("encoder", new StringEncoder());//自定义handlerpipeline.addLast("clientHandler", new GroupChatClientHandler());}
}

(3) GroupChatClient

public class GroupChatClient {public static void main(String[] args) {EventLoopGroup group = new NioEventLoopGroup();try {Bootstrap bootstrap = new Bootstrap();bootstrap.group(group).channel(NioSocketChannel.class).handler(new GroupChatClientChannelInitializetr());ChannelFuture channelFuture = bootstrap.connect(GroupChatConsts.host, GroupChatConsts.port).sync();//输入信息Channel channel = channelFuture.channel();Scanner scanner = new Scanner(System.in);while (scanner.hasNext()) {String msg = scanner.nextLine();channel.writeAndFlush(msg + "\n");}} catch (InterruptedException e) {e.printStackTrace();} finally {group.shutdownGracefully();}}}

3 测试

(1) 启动服务端,启动3个客户端

(2) 发送消息


Netty实现群聊系统相关推荐

  1. Netty基础,Netty实现群聊系统

    NIO群聊系统 这里面的知识比较全面,用到了我们之前学习的三大组件,首先我先来给大家介绍本系统的功能 服务端功能 最基本的当然是注册功能,也就是将serverSocketChannel注册进Selec ...

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

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

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

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

  4. Netty学习笔记:二、NIO网络应用实例-群聊系统

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

  5. Java基础之《netty(18)—群聊系统》

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

  6. Netty:实现群聊系统+自定义名称+空闲检测+Protobuf

    作为一个Java小白,持续学习是不可避免的,近期学习了Netty的相关知识,使用Netty实现了一个简单的群聊系统,使用Protobuf进行传输,支持空闲心跳检测,并且可以自定义群聊名称,所以写了此篇 ...

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

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

  8. Java NIO网络编程之群聊系统

    概述 对ServerSocketChannel.SocketChannel.SelectionKey有一定的理解和了解对应API. NIO非阻塞网络编程相关关系梳理: 以下概念: ServerSock ...

  9. Java NIO群聊系统

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

  10. 4.基于NIO的群聊系统

    [README] 1.本文总结自B站<netty-尚硅谷>,很不错: 2.文末有错误及解决方法: [1]群聊需求 1)编写一个 NIO 群聊系统,实现服务器端和客户端之间的数据简单通讯(非 ...

最新文章

  1. DOM(Document object madle) 文档对象模型: 元素节点 文本节点 属性节点
  2. python asyncio文件操作_Python asyncio文档阅读摘要
  3. java 控制台刷屏 dll_控制台被警告刷屏 · Issue #IXD8V · 卓源软件/JeeSite 4.2 - Gitee.com...
  4. 认证篇——单向散列函数
  5. C 结构体嵌套一级指针 二级指针 动态分配内存
  6. mysql 全文本检索的列_Mysql 全文本检索
  7. [改善Java代码]若有必要,使用变长数组
  8. c# 操作word中在右下角插入图片
  9. 时光就是一颗巨大的牛轧糖
  10. ThinkPhp框架:父类及表单验证
  11. Android OpenGL 开发
  12. 吉首大学第十届“新星杯”大学生程序设计大赛(暨新生网络同步赛)
  13. Android官方源码资料博客
  14. matlab钢材切割,一种基于MATLAB的钢材裂纹扩展速率试验数据处理方法
  15. Microsoft .Net Remoting系列专题之一:.Net Remoting基础篇
  16. 【综述】Deep Learning for Visual Tracking: A Comprehensive Survey-2019
  17. Wlan学习—无线网络安全
  18. ViewBinding使用时出现Could not find method viewBinding() for arguments错误
  19. 智能驾驶大数据是什么?传统车企如何升级?
  20. 电脑丢失的dll文件怎么一键修复?修复dll方法分享

热门文章

  1. 自动脚本 android,原神自动脚本全功能版
  2. MapGIS6.7环境设置
  3. svn 创建分支,合并分支
  4. 传奇病毒劫持流量手法分析
  5. i510400和i59400f哪个好?有什么区别
  6. 计算机键盘调亮度,电脑屏幕亮度怎么调
  7. python之scipy库详解
  8. python执行源程序的方式是_python源程序执行的方式
  9. 1.4多媒体技术的发展历史
  10. 2021年4月自考04741计算机网络原理试卷