查看原文
其他

Spring boot + LayIM + t-io 单聊群聊的实现

2017-11-24 丶Pz 开源中国


摘要: 一个基于Spring boot,t-io的通讯框架,LayIM的实现。


前言


新人上任三把火,除了新人报道篇,本篇可以算是正式的第一篇了,本文是来自博客园《从零一起学Spring Boot之LayIM项目长成记》系列的第六篇,原标题为:《从零一起学Spring Boot之LayIM项目长成记(六)用户登录验证和单聊群聊的实现》。


功能介绍


先简单介绍一下项目背景,突然发现, 项目背景就是标题。。。直接进入正题吧。当然除了LayIM我已经实现过N个版本以外,Springboot和t-io都是初次使用,难免有使用不当之处,欢迎批评指正。


其实从标题就可以看出来,单聊和群聊功能无非就是借助通讯框架来实现时时通讯,单聊,1对1,群聊1对多,或者1对1也能理解成为两个人的群聊。不过t-io相对于springboot中已经封装好的websocket来说,具有更强的开发灵活性,并且自带丰富功能的API。不过不得不说,这个框架用起来还真是挺爽的,尤其当你更加明确消息的走向的时候,你会发现,原来通讯这么好玩。另外,我的开发过程中和LayIM的业务结合比较强,所以通用性较差。学习更高级的部分可以去看 tio-im,它的实现就比较牛啦。


废话少说,直接上代码。


单聊


在文章 从零一起学Spring Boot之LayIM项目长成记(五)websocket 中已经实现了消息的发送,所以这里不在赘述,下文中将会详细的讲到消息发送以及处理上的细节。


前半段是js介绍部分,无兴趣的可以直接跳到server端


首先,我自己封装了一个简单的适用于Layui开发模式的socket模块。Layui模块化开发官网示例如下:



 (题外话,osc的代码段还是比较好看的)同样的道理,照葫芦画瓢,先搭建一个模型再说:



基架搭建完了,剩下的就是填充功能。那么socket.js要做什么事情呢?


  • 连接服务器

  • 监听各种事件

  • 要能灵活配置

  • 消息发送和接收(监听)


从以上几点呢,就可以分模块写代码了。首先连接服务器,很简单,就是判断支不支持websocket,做个提示,然后监听成功失败等事件。



事件监听机制是我参考的 layim.js 源码中的写法。



上文中 regWsEvent 源码,其实就是ws的几个默认事件,然后让我转化成了socket的监听事件方式。



所以在外部调用是酱紫的:



运行一下,看看打印,基本没啥问题


    


接触过的websocket的,或者做过demo的,上边的代码都不难理解,只不过我做了稍许封装。在进入服务端开发部分之前,先简单介绍一个layim中的聊天api,首先他发送消息的格式是酱紫的:



从以上截图可以看出来,消息体中包含了发送人的ID,头像,昵称等信息,接收人(群)的ID,头像,昵称等信息,并且消息类型是由 type 来区分的,一个 friend,一个group。但是我的消息体设计是不需要这么多字段的。



为什么只要接收方ID和内容呢?因为,发送人就是当前登录用户,所以头像昵称可以从服务端获取,当然你想直接从客户端传给服务端也没有问题。


另外由于群聊和单聊的结构差不多,只是type的区分。(当然群聊还有一个小细节处理,下文中会讲到)所以我们只要这么简单一个消息结构就可以满足客户端发送了。所以在LayIM发送事件中,编写如下代码:



哦了,客户端发送完了,服务端得解析吧。(下文中的内容稍微和第五篇中有些重复,不过没关系,着重细节处理)


在LayimServerAioHandler中,代码执行到handleDetail时候,就需要对消息进行处理了。



获取消息处理器部分呢,其实就是初始化的时候将各种消息处理类实例化加入到一个hashmap中



消息处理器接收到消息,进行处理,这里需要强调一下的是,消息转换厚的结果只是略有不同,比如,区分type是friend还是group,id的设置。其他都是一样的,最主要的区别在于,一个是给单个对象发送,说白了,就是调用send方法,另外一个是调用sendToGroup方法。下面看详细代码。



中间消息体的转化部分,其中的注释已经很详细了。上文中提到群组发送的细节就是,需要带上from参数,否则自己也会接收到群组消息,然后会导致重复加载消息的情况。客户端会根据from进行筛消息处理。



上文中讲了这么多,可能还会有很多同学云里雾里的,下面做一下演示,给大家看看流程打印。



客户端打印:



我们已经看到客户端打印出了消息。(为了测试,我让用户发送的消息在给自己发回来),然后直接调用layim的接口即可。 layim.getMessage(msg)



效果如下(临时会话的原因是因为我自己和自己发消息,如果是和好友的话,不会出现这种情况):



群聊


下面在将一下群消息,群消息的处理和单聊差不多,只要,继承单聊消息处理器,重写 send方法即可



群消息演示:



问题1:我的消息重复了

问题2:为什么左边的框也是我,但是消息在左边。


问题1解决

通过from参数进行判断


问题2解决

写一个临时变量,判断是否该窗口发送的消息



最后演示效果:


总结


本文基本把群聊和单聊的各种细节以及消息处理流程介绍完了。OSChina 处女篇宣告完结。编辑起来还挺爽的,哈哈哈哈


参考资料:


  • https://gitee.com/tywo45/t-io

  • https://gitee.com/xchao/tio-im


本文代码地址:https://github.com/fanpan26/SpringBootLayIM 欢迎star,博客会继续更新,最后再次感谢 t-io 原作者的优秀框架。




感恩节福利

11 月 27 日之前,只要在【你谈见解我送书:你所不了解的 Kafka | 感恩节福利】文末留言你在试读书籍第一章后的见解,就有机会获得文中提及技术书籍一本!快来留言吧,说不定中奖的就是你哦!!



推荐阅读

Linux 运维人员最常用 150 个命令汇总

阿里 Dubbo 疯狂更新,关 Spring Cloud 什么事?

TIOBE 11 月编程语言排行榜,脚本语言怎么了?

用 Vue 做一个酷炫的 menu

点击“阅读原文”查看更多精彩内容

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存