你好,我是彤哥,本篇是netty系列的第四篇。

欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识。

简介

上一章我们一起学习了Java中的BIO/NIO/AIO的故事,本章将带着大家一起使用纯纯的NIO实现一个越聊越上瘾的“群聊系统”。

业务逻辑分析

首先,我们先来分析一下群聊的功能点:

(1)加入群聊,并通知其他人;

(2)发言,并通知其他人;

(3)退出群聊,并通知其他人;

一个简单的群聊系统差不多这三个功能足够了,为了方便记录用户信息,当用户加入群聊的时候自动给他分配一个用户ID。

业务实现

上代码:

// 这是一个内部类
private static class ChatHolder {// 我们只用了一个线程,用普通的HashMap也可以static final Map<SocketChannel, String> USER_MAP = new ConcurrentHashMap<>();/*** 加入群聊* @param socketChannel*/static void join(SocketChannel socketChannel) {// 有人加入就给他分配一个id,本文来源于公从号“彤哥读源码”String userId = "用户"  ThreadLocalRandom.current().nextInt(Integer.MAX_VALUE);send(socketChannel, "您的id为:"   userId   "\n\r");for (SocketChannel channel : USER_MAP.keySet()) {send(channel, userId   " 加入了群聊"   "\n\r");}// 将当前用户加入到map中USER_MAP.put(socketChannel, userId);}/*** 退出群聊* @param socketChannel*/static void quit(SocketChannel socketChannel) {String userId = USER_MAP.get(socketChannel);send(socketChannel, "您退出了群聊"   "\n\r");USER_MAP.remove(socketChannel);for (SocketChannel channel : USER_MAP.keySet()) {if (channel != socketChannel) {send(channel, userId   " 退出了群聊"   "\n\r");}}}/*** 扩散说话的内容* @param socketChannel* @param content*/public static void propagate(SocketChannel socketChannel, String content) {String userId = USER_MAP.get(socketChannel);for (SocketChannel channel : USER_MAP.keySet()) {if (channel != socketChannel) {send(channel, userId   ": "   content   "\n\r");}}}/*** 发送消息* @param socketChannel* @param msg*/static void send(SocketChannel socketChannel, String msg) {try {ByteBuffer writeBuffer = ByteBuffer.allocate(1024);writeBuffer.put(msg.getBytes());writeBuffer.flip();socketChannel.write(writeBuffer);} catch (Exception e) {e.printStackTrace();}}
}

服务端代码

服务端代码直接使用上一章NIO的实现,只不过这里要把上面实现的业务逻辑适时地插入到相应的事件中。

(1)accept事件,即连接建立的时候,说明加入了群聊;

(2)read事件,即读取数据的时候,说明有人说话了;

(3)连接断开的时候,说明退出了群聊;

OK,直接上代码,为了与上一章的代码作区分,彤哥特意加入了一些标记:

public class ChatServer {public static void main(String[] args) throws IOException {Selector selector = Selector.open();ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.bind(new InetSocketAddress(8080));serverSocketChannel.configureBlocking(false);// 将accept事件绑定到selector上serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {// 阻塞在select上selector.select();Set<SelectionKey> selectionKeys = selector.selectedKeys();// 遍历selectKeysIterator<SelectionKey> iterator = selectionKeys.iterator();while (iterator.hasNext()) {SelectionKey selectionKey = iterator.next();// 如果是accept事件if (selectionKey.isAcceptable()) {ServerSocketChannel ssc = (ServerSocketChannel) selectionKey.channel();SocketChannel socketChannel = ssc.accept();System.out.println("accept new conn: "   socketChannel.getRemoteAddress());socketChannel.configureBlocking(false);socketChannel.register(selector, SelectionKey.OP_READ);// 加入群聊,本文来源于公从号“彤哥读源码”ChatHolder.join(socketChannel);} else if (selectionKey.isReadable()) {// 如果是读取事件SocketChannel socketChannel = (SocketChannel) selectionKey.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);// 将数据读入到buffer中int length = socketChannel.read(buffer);if (length > 0) {buffer.flip();byte[] bytes = new byte[buffer.remaining()];// 将数据读入到byte数组中buffer.get(bytes);// 换行符会跟着消息一起传过来String content = new String(bytes, "UTF-8").replace("\r\n", "");if (content.equalsIgnoreCase("quit")) {// 退出群聊,本文来源于公从号“彤哥读源码”ChatHolder.quit(socketChannel);selectionKey.cancel();socketChannel.close();} else {// 扩散,本文来源于公从号“彤哥读源码”ChatHolder.propagate(socketChannel, content);}}}iterator.remove();}}}
}

测试

打开四个XSHELL客户端,分别连接telnet 127.0.0.1 8080,然后就可以开始群聊了。

彤哥发现,自己跟自己聊天也是会上瘾的,完全停不下来,不行了,我再去自聊一会儿^^

总结

本文彤哥跟着大家一起实现了“群聊系统”,去掉注释也就100行左右的代码,是不是非常简单?这就是NIO网络编程的魅力,我发现写网络编程也上瘾了^^

问题

这两章我们都没有用NIO实现客户端,你知道怎么实现吗?

提示:服务端需要监听accept事件,所以需要有一个ServerSocketChannel,而客户端是直接去连服务器了,所以直接用SocketChannel就可以了,一个SocketChannel就相当于一个Connection。

最后,也欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识。

4. 彤哥说netty系列之Java NIO实现群聊(自己跟自己聊上瘾了)相关推荐

  1. java nio netty 教程,4. 彤哥说netty系列之Java NIO实现群聊(自己跟自己聊上瘾了),netty实现...

    4. 彤哥说netty系列之Java NIO实现群聊(自己跟自己聊上瘾了),netty实现 你好,我是彤哥,本篇是netty系列的第四篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识 ...

  2. java 仿qq庅,4. 彤哥说netty系列之Java NIO实现群聊(自己跟自己聊上瘾了)

    你好,我是彤哥,本篇是netty系列的第四篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们一起学习了Java中的BIO/NIO/AIO的故事,本章将带着大家一起使 ...

  3. java channel源码_彤哥说netty系列之Java NIO核心组件之Channel

    你好,我是彤哥,本篇是netty系列的第五篇. 欢迎来我的工从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们一起学习了如何使用Java原生NIO实现群聊系统,这章我们一起来看看Ja ...

  4. java nio attachment_7. 彤哥说netty系列之Java NIO核心组件之Selector

    --日拱一卒,不期而至! 你好,我是彤哥,本篇是netty系列的第七篇. 简介 上一章我们一起学习了Java NIO的核心组件Buffer,它通常跟Channel一起使用,但是它们在网络IO中又该如何 ...

  5. java channel源码_5. 彤哥说netty系列之Java NIO核心组件之Channel

    你好,我是彤哥,本篇是netty系列的第五篇. 简介 上一章我们一起学习了如何使用Java原生NIO实现群聊系统,这章我们一起来看看Java NIO的核心组件之一--Channel. 思维转变 首先, ...

  6. 6. 彤哥说netty系列之Java NIO核心组件之Buffer

    --日拱一卒,不期而至! 你好,我是彤哥,本篇是netty系列的第六篇. 简介 上一章我们一起学习了Java NIO的核心组件Channel,它可以看作是实体与实体之间的连接,而且需要与Buffer交 ...

  7. java aio nio bio_3. 彤哥说netty系列之Java BIO NIO AIO进化史

    你好,我是彤哥,本篇是netty系列的第三篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们介绍了IO的五种模型,实际上Java只支持其中的三种,即BIO/NIO/ ...

  8. 1. 彤哥说netty系列之开篇(有个问卷调查)

    你好,我是彤哥,本篇是netty系列的第一篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 本文主要讲述netty系列的整体规划,并调查一下大家喜欢的学习方式. 知识点 ne ...

  9. 2. 彤哥说netty系列之IO的五种模型

    你好,我是彤哥,本篇是netty系列的第二篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 本文将介绍linux中的五种IO模型,同时也会介绍阻塞/非阻塞与同步/异步的区别. ...

最新文章

  1. 计算机天才Aaron Swartz 名作 《如何提高效率》——纪念真正的“hacker!
  2. 使用jenkins进行持续集成
  3. 动手开发自己的第一个 composer 包
  4. 小学生python-小学生学python(五)
  5. 视频培训网站发布问题
  6. numpy.argsort详解
  7. 同余方程———扩展欧几里得
  8. 全球及中国牵引螺丝行业规模现状与“十四五”发展前景预测报告2021-2027年版
  9. Python实训day14am【Python网络爬虫综合大作业-答辩】
  10. Spring–添加SpringMVC –第1部分
  11. Effective Java~37. 用EnumMap 代替序数索引
  12. 手机浏览器中屏蔽img的系统右键菜单context menu
  13. Eclipse中错误为 Access restriction 的解决方案
  14. 吴颖二:12.27 什么是现货,如何操作才能盈利
  15. 手把手教你玩转CSS3 3D技术
  16. mysql只导出表数据_MySQL 如何只导出 指定的表 的表结构和数据 ( 转 )
  17. 大数据技术原理与应用----大数据概述
  18. GPS学习之二:AGPS,GPS,DGPS 认识
  19. svn里 is already locked
  20. 台式计算机密码忘了怎么办,台式机开机密码忘了怎么办

热门文章

  1. 打孔纸带计算机运行原理
  2. Faiss 相似度搜索使用余弦相似性
  3. 34.发送ICMP时间戳请求
  4. Dashboard的安装及其配置
  5. python 小说 小说_如何使用python上小说网爬网络小说?
  6. JAVA ECLIPSE安装
  7. 四不帮你弄懂网络编程之最后一步
  8. Java虚拟机学习与总结(二)
  9. 知音微服务平台网上订烟_新商盟网上订烟登录工具
  10. 考研英语核心词汇梳理一