一款聊天软件,客户端使用多种语言开发GUI,主要是Qt6,服务端使用go语言。
运行机制:一切的一切都是客户端与服务端的沟通,不存在客户端之间的连接。所有消息由服务端进行处理,转发。
1、基础功能
用户注册、登录、登出、聊天(暂不考虑群聊功能)。
好友:添加好友、删除好友、查找好友。
消息:未读消息
2、高级功能
验证码(邮箱,为什么不考虑短信?因为短信要花钱哈哈哈)。
-
1、通信
基于Zinx框架[https://github.com/aceld/zinx][Zinx框架],并对框架进行了一些美化,来符合气质,气质不能输。
1)通信协议 初步想法为使用protobuf协议,以应对高速传输。(不知道能不能弥补RSA加密解密速度慢的问题)
报头+包体,使用框架内的协议进行通信
报头:包含数据长度,请求服务的类型id,共8个字节。
包体:数据自身(根据需要进行RSA加密)
2)数据安全
采用双向的RSA加密方式,客户端与服务端各持有不同的私钥,和对方私钥所对应的公钥。通信前将数据使用公钥加密,接收数据后再使用私钥解密。用户登录成功后,服务端会生成有效期30分钟的Token,每29分钟重新生成新的Token发送给客户端(是客户端从服务端要Token还是服务端发送Token还有待考虑)。
3)连接合法性验证
在建立连接(客户请求登录),需完成猜谜,解决一段密码。生成token,防止非法socket连接。
-
2、数据库
使用MySQL + Redis数据库 + MongoDB(初步构想,关于数据库的构架还有待细研究)。
MySQL存储用户的账户、好友信息。对各个表尽可能添加了索引,查询时考虑好加锁问题。
Redis存储用户Token信息,用户验证码,及其他缓存信息。
MongoDB存储用户消息记录,及其他大数据信息。
-
3、编程语言
服务端使用go语言,因为go语言操作数据库比较方便,体量小,高并发多线程处理比较强悍。
客户端使用多种语言分别实现,目前考虑到的有:Qt6、C#、go、Qt Quick、python with pyqt5
由于python的特性和pyqt5的限制,python的gui实现还在考虑,主要是因为pyqt5的自定义信号槽机制还需要再研究研究。
go语言实现gui初步采用fyne GUI库 v2,偶然发现的一个go gui框架,试了一下感觉还行,用着还算舒服,可惜没有类似qt designer那样的可视化画控件,只能通过码代码一点一点试,还有就是中文支持需要自己在go main的init中设置环境变量。具体其他还在研究。
对于Qt6,采用的是cmake的编译方式,属于尝尝螃蟹。移植回Qt5也很简单,只要在在pro文件中配置好openssl的头文件,链接库,protobuf的头文件,链接库即可。还要定义好socket的host,port,time_out三个宏,当然直接写死在代码里也是可以的。
go语言环境,protobuf环境(protoc和go的插件),mysql,redis,openssl。
用到的第三方库:Zinx框架,color库,其具体已写在go.mod文件中。
-
MySQL导入server根目录下的sql文件,所有的表为空表,其中tb_user_id表为id池,需要提前生成许多id供用户注册账户时使用。
-
在MySQL中执行:
call add_id(num) #num为生成id的数量,自行修改,根据需要进行设置。
在id池用完后,即tb_user_id表内status字段不存在unused值,可继续执行上述存储过程。注意此方法会产生表锁,要在空闲时间或者服务器停机时执行,放在并发出现阻塞等意外。
-
生成RSA公钥和私钥
openssl genrsa -out private.pem 2048 # 私钥
openssl rsa -in private.pem -pubout -out public.pem # 根据私钥生成公钥
将公钥提供给客户端(客户端未开发),私钥存放在服务端可执行文件的同级目录内。
-
编译
go build
-
运行目录内的可执行文件
zinx框架内有很多不必要的fmt.Println语句用于控制台输出,建议根据需求自行修改zinx框架源码。
测试框架使用goconvey。
尚未开发,可以自行根据需要,使用各种语言的socket编程进行消息测试。使用前要使用protoc去protos文件夹内生成好相应的proto代码来解析消息。
当前完成了Qt6客户端的简易版登陆注册的gui,并实现了检查连接合法性的功能。