一、即时通信APP开发前言
学习能把知识学到手,讲究的是实践,在小傅哥编写的文章中,基本都是以实践代码验证结果为核心,讲述文章内容。😁从小我就喜欢动手,就以一个即时通信的项目为例,已经基于不同技术方案实现了5、6次,仅为了实践技术,截图如下:
- 有些是刚学完Socket和Swing的时候,想动手试试这些技术能不能写个QQ出来。
- 也有的是因为实习培训需要完成的项目,不过在有了一些基础后,一周时间就能写完全部功能。
- 虽然这些项目在现在看上去还是丑丑的界面,以及代码逻辑可能也不是那么完善。但放在学习阶段的每一次实现中,都能为自己带来很多技术上的成长。
那么,这次IM实践的机会给你,希望你能用的上!接下来我会给你介绍一个IM的系统架构、通信协议、单聊群聊、表情发送、UI事件驱动等各项内容,以及提供全套的源码让你可以上手学习。
二、演示
在开始学习之前,先给大家演示下这套仿照PC端微信界面的IM系统运行效果。
聊天页面
添加好友
视频演示
三、系统设计
在这套IM
中,服务端采用DDD
领域驱动设计模式进行搭建。将 Netty 的功能交给 SpringBoot
进行启停控制,同时在服务端搭建控制台可以非常方便的操作通信系统,进行用户和通信管理。在客户端的建设上采用UI
分离的方式进行搭建,以保证业务代码与UI
展示分离,做到非常易于扩展的控制。
另外在功能实现上包括;完美仿照微信桌面版客户端、登录、搜索添加好友、用户通信、群组通信、表情发送等核心功能。如果有对于实际需要使用的功能,可以按照这套系统框架进行扩展。
- UI开发:使用
JavaFx
与Maven
搭建UI桌面工程,逐步讲解登录框体、聊天框体、对话框、好友栏等各项UI展示及操作事件。从而在这一章节中让Java 程序员学会开发桌面版应用。 - 架构设计:在这一章节中我们会使用DDD领域驱动设计的四层模型结构与Netty结合使用,架构出合理的分层框架。同时还有相应库表功能的设计。相信这些内容学习后,你一定也可以假设出更好的框架。
- 功能实现:这部分我们主要将通信中的各项功能逐步实现,包括;登录、添加好友、对话通知、消息发送、断线重连等各项功能。最终完成整个项目的开发,同时也可以让你从实践中学会技能。
四、UI开发
1. 整体结构定义、侧边栏
聊天窗体,相对于登陆窗体来说,聊天窗体的内容会比较多,同时也会相对复杂一些。因此我们会分章节的逐步来实现这些窗体以及事件和接口功能。在本篇文章中我们会主要讲解聊天框体的搭建以及侧边栏 UI 开发。
- 首先是我们整个聊天主窗体的定义,是一块空白面板,并去掉默认的边框按钮 (最小化、退出等)
- 之后是我们左侧边栏,我们称之为条形 Bar,功能区域的实现。
- 最后添加窗体事件,当点击按钮时变换
内容面板
中的填充信息。
2. 对话聊天框
对话框选中后的内容区域展现,也就是用户之间信息发送和展现。从整体上看这是一个联动的过程,点击左侧的对话框用户,右侧就有相应内容的填充。那么右侧被填充对话列表 ListView 需要与每一个对话用户关联,点击聊天用户的时候,是通过反复切换填充的过程。
- 点击左侧的每一个对话框体,右侧聊天框填充内容即随之变化。同时还有相应的对话名称也会也变化。
- 对话框中左侧展示好友发送的信息,右侧展示个人发送的信息。同时消息内容会随着内容的增多而增加高度和宽度。
- 最下面是文本输入框,在后面的实现里我们文本输入框采用公用的方式进行设计,当然你也可以设计为单独的个人使用。
3. 好友栏
大家都经常使用 PC 端的微信,可以知道在好友栏里是分了几段内容的,其中包含;新的朋友、公众号、群组和最下面的好友。
- 最上面的搜索框这部分内容不变,和前面的一样。我们目前使用的方式是 fxml 设计,例如这部分是通用功能,可以抽取出来放到代码中,设计成一个组件元素类。
- 经过我们的分析,在使用 JavaFx 组件开发为基础下,这部分是一种嵌套 ListView,也就是最底层的面板是一个 ListView,好友和群组有各是一个 ListView,这样处理后我们会很方便的进行数据填充。
- 另外这样的结构主要有利于在我们程序运行过程中,如果你添加了好友,那么我们需要将好友信息刷新到好友栏中,而在数据填充的时候,为了更加便捷高效,所以我们设计了嵌套的 ListView。如果还不是特别理解,可以从后续的代码中获得答案。
4. 事件定义
在桌面版 UI 开发中,为了能使 UI 与业务逻辑隔离,需要在我们把 UI 打包后提供出操作界面的展示效果的接口以及界面操作事件抽象类。那么可以按照下图理解;
序号 | 接口名 | 描述 |
---|---|---|
1 | void doShow() | 打开窗口 |
2 | void setUserInfo(String userId, String userNickName, String userHead) | 设置登陆用户 ID、昵称、头像 |
3 | void addTalkBox(int talkIdx, Integer talkType, String talkId, String talkName, String talkHead, String talkSketch, Date talkDate, Boolean selected) | 填充对话框列表 |
4 | void addTalkMsgUserLeft(String talkId, String msg, Date msgData, Boolean idxFirst, Boolean selected, Boolean isRemind) | 填充对话框消息 – 好友 (别人的消息) |
- 以上这些接口就是我们目前 UI 为外部提供的所有行为接口,这些接口的一个链路描述就是;打开窗口、搜索好友、添加好友、打开对话框、发送消息。
五、通信设计
1. 系统架构
在前面我们说到更适合的架构,才是符合你当下需要最好的架构。那么怎么设计这样架构呢,基本就是要找到符合点的目标。我们之所以这样设计是为什么,那么在这个系统里有如下几点;
- 我们系统在服务端要有 web 页面进行管理通信用户以及服务端的控制和监控。
- 数据库的对象类,不要被外部污染,要有隔离性。比如说;你的数据库类暴漏给外部做展示类使用了,那么现在需要增加一个字段,而这个字段又不是你数据库存在的属性。那么这个时候就已经把数据库类污染了。
- 因为目前我们都是在 Java 语言下实现 Netty 通信,那么服务端与客户端都会需要使用到通信过程中的协议定义和解析。那么我们需要抽离这一层对外提供 Jar 包。
- 接口、业务处理、底层服务、通信交互,要有明确的区分和实现,避免造成混乱难以维护。
结合我们上面这四点的目标,你头脑中有什么模型结构体现了呢?以及相应的技术栈选择上是否有计划了?接下来我们会介绍两种架构设计的模型,一种是你非常熟悉的 MVC
,另外一种是你可能听说过的 DDD
领域驱动设计。
2. 通信协议
从图稿上来看,我们在传输对象的时候需要在传输包中添加一个 帧标识 以此来判断当前的业务对象是哪个对象,也就可以让我们的业务更加清晰,避免使用大量的 if 语句判断。