我想到的Netty功能,别人已经实现了

举报
赵KK日常技术记录 发表于 2023/06/24 13:38:01 2023/06/24
【摘要】 Netty是年初最先学习的框架,近期的图书租借系统想要用上聊天功能,实现一对一对话聊天,在用户登录服务端时,获取用户ip与id绑定,放入channelgroup,每次循环遍历这个ip对应的channel,否则返回false,在用户状态取到是否在线,在线状态属于handler消息功能。1.一对一聊天2.展示在线人数3.登录验证4.输入框优化5.可支持表情开源万岁当寻找Netty一对一聊天功能实...

Netty是年初最先学习的框架,近期的图书租借系统想要用上聊天功能,实现一对一对话聊天,在用户登录服务端时,获取用户ip与id绑定,放入channelgroup,每次循环遍历这个ip对应的channel,否则返回false,在用户状态取到是否在线,在线状态属于handler消息功能。

1.一对一聊天

2.展示在线人数

3.登录验证

4.输入框优化

5.可支持表情

开源万岁

当寻找Netty一对一聊天功能实现的时候,除了重温下功能点,还能发现新的东西,一个小小的demo,别人却不是这么做的,细化到验证,还考虑到性能,看下实现效果页面

请在此添加图片描述

需要昵称输入,登录后不是简单的数据新增

 private static ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true);
 private static ConcurrentMap<Channel, UserInfo> userInfos = new ConcurrentHashMap<>();
 private static AtomicInteger userCount = new AtomicInteger(0);

读写锁;

并发包;

原子计数;

因为最终实现用户的在线人数统计,用了原子类的AtomicInteger

 private static AtomicInteger uidGener = new AtomicInteger(1000);

    private boolean isAuth = false; // 是否认证
    private long time = 0;  // 登录时间
    private int userId;     // UID
    private String nick;    // 昵称
    private String addr;    // 地址
    private Channel channel;// 通道

登录用户信息,确定昵称,获取ip,每一个用户ip,channel一一对应放入channelGroup。

请在此添加图片描述

如何发送消息?

在消息处理Handler中,重写channelread0方法

1.获取是否存在此用户信息的channel

2.存在将用户id,昵称,接收到的消息广播到页面显示

3.消息不为null,读写锁加锁,找到当前用户的channel

4.遍历用户信息,通过netty写入回调返回

 if (msg instanceof FullHttpRequest) {
            handleHttpRequest(ctx, (FullHttpRequest) msg);
        } else if (msg instanceof WebSocketFrame) {
            handleWebSocket(ctx, (WebSocketFrame) msg);
        }

将Handler接受接入到Server

1.定时关闭失效的channel

2.定时向客户端ping消息

Netty的消息处理流程

定义好父子线程组–>在childInitializer定义好相关处理通道处理器–>自己提供处理器在回调

现在开始回调

.childHandler(new ChannelInitializer<SocketChannel>() {

                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                       将group放入消息管道
                        ch.pipeline().addLast(defLoopGroup,
                                //请求解码器
                                new HttpServerCodec(),
                                //将多个消息转换成单一的消息对象
                                new HttpObjectAggregator(65536),
                                //支持异步发送大的码流,一般用于发送文件流
                                new ChunkedWriteHandler(),
                                //检测链路是否读空闲
                                new IdleStateHandler(60, 0, 0),
                                //处理握手和认证
                                new UserAuthHandler(),
                                //处理消息的发送
                                new MessageHandler()
                        );
                    }
                });

定时处理失效消息

 // 定时扫描所有的Channel,关闭失效的Channel
            executorService.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    logger.info("scanNotActiveChannel --------");
                    UserInfoManager.scanNotActiveChannel();
                }
            }, 3, 60, TimeUnit.SECONDS);

            // 定时向所有客户端发送Ping消息
            executorService.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    UserInfoManager.broadCastPing();
                }
            }, 3, 50, TimeUnit.SECONDS);

前端页面没有什么变化。

1.绑定websocket

2.websocket调用onmessage处理消息

window.socket = new WebSocket("ws://localhost:9688/websocket")

处理技术:

1.线程池

2.Lambad表达式

3.读写锁提高性能

4.原子引用保证原子性,线程安全

debug

请在此添加图片描述

用户登录,判断是否是给定的消息类型

获取昵称,用户信息,code码

==success,保存用户信息

第一次登陆没有此用户id与channel,不广播消息

用户计数0 broadCastPing userCount: 0

当发送消息到页面时

请在此添加图片描述

触发定时消息广播,遍历size

处理消息ctx.fireChannelRead(frame.retain());

此时广播用户计数broadCastPing userCount: 1

websocket实现了真正意义上的客户端与服务器端的长连接,节省带宽,而关注内容本身

      websocket:1--:双向数据传递;

                           2--:基于Http

                           3--:非浏览器场合

请在此添加图片描述

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。