即时通讯程序总结
文章目录
- 前言
- 主要思路
- 事件监听
- 消息格式设计
- 消息分发
- 界面
- 效果展示
前言
之前写了一个即时通讯桌面应用程序,使用JavaFX进行开发,使用socket来完成客户端之间的消息传递。做一下总结,程序写得比较简单,存在很多不够好的地方。
项目已上传,感兴趣的同学可以了解一下
项目地址: https://github.com/godelgnisEJW/IM
主要思路
我做的聊天程序有服务端和客户端。
- 主要完成的功能有:用户登陆功能,普通消息发送功能(文字+emoji表情),文件传输功能,视频通信功能
- 服务端主要负责客户端登陆时的信息验证和负责接受客户端的上线下线的状态消息,维护在线用户列表,并且向客户端更新在线用户列表消息。并且服务端还可以管理用户信息和在聊天大厅中聊天,充当管理员的角色。
- 客户端需要与客户端之间一直维持着socket连接,如果连接断开,服务端会判定为用户下线,并且更新用户列表。客户端与客户端之间进行聊天时,所传递的消息不需要经过服务端,也就是说,此时的客户端相当与有一个内置的服务器,可以监听其他客户端发送的连接请求,并且使用该socket连接来完成通信。
- 因此服务端程序只开放一个端口,而客户端启动时会使用一个随机端口,客户端登陆成功后会启动一个内置的服务器,客户端会把内置服务器的监听端口向服务端进行汇报登记,服务在更新在线用户列表时会把客户端相对应的内置服务器端口一并更新了。然后不用用户之间进行通信时,如果之前已经有用于通信的连接,那么就使用这个已存在的连接,如果是第一次与这个用户进行通信,那么就向这个用户的监听端口发起连接请求,然后进行通信。
使用这种方式,则客户端之间总的只需要3个socket连接即可实现客户端之间相互通信。如果不采用这种方式,每与一个新的用户通信就建立一个新的socket连接,那么就会多建立一倍的socket。
事件监听
我自定义了程序中的几个事件,分别是程序启动事件(需要完成程序初始化工作),程序关闭事件(需要完成程序的收尾工作,包括用户信息保存和临时文件的删除等),消息事件(需要进行消息分发)。
使用了观察者模式和中介者模式
在程序启动,程序关闭和接收到消息时,会分别产生相应事件类型的事件,触发事件分派器分派消息。事件处理器需要到事件分派器进行注册,处理相应的事件。其中EventDispatch既扮演观察者的角色,又扮演中介者的角色。
消息格式设计
以下是我设计的消息格式
格式比较简单,每条消息的第一个字节为这条消息的消息类型,然后接着的四个字节为消息内容的长度,紧接着的就是消息的内容了。客户端在接受消息的时候就可以按照固定的格式读取指定的字节内容,消息内容则根据4个字节的消息长度读取指定的字节数,这样就可以解决TCP消息无边界的问题了。
最初的消息格式的设计太过于简单,以至于后续要扩展消息格式时不好用,缺少参数的设置。。。
如果重新设计的话,我会设计成这样
这样设计的话消息就能带上参数,消息类型和内容的扩展会更加容易。
消息分发
消息的分发主要使用中介者模式,程序中定义的多个消息解析器需要在MessageDispatch进行注册。MessageDispatch在接收到消息事件时,会将接受到的消息进行分发,不同的消息类型有不同的解析方式。
界面
界面主要使用Scence Builder来完成,操作简便,可以快速完成界面的设计,有一点值得一提的是,在设计的时候我习惯用AnchorPane作为最底层的面板,该面板上的元素位置可以很容易地进行调整,而不像BorderPane或者StackPane那样,面板上元素的位置是固定的,不容易进行调整。
效果展示
视频功能就发几张图片好了
ZeroRains: 官方的例子是指一台机器启动多个container还是多个机器分别启动一个container?
erxiaoouba: 怎么才能知道哪个是leader呢
Hdd会得多-: totalTaskSlots是在flink-conf.yaml文件里设置对吗,为什么我的总是修改不了,重启容器后就会变成1
肖焱午: 这是亿点点细节
L_KingC: 请问找到原因了吗