美文网首页Golang相关Go知识库IOS IM
golang写的即时通讯服务器

golang写的即时通讯服务器

作者: AlberLiu | 来源:发表于2018-11-12 16:15 被阅读23次

    1 简要介绍

    goim是一个简单的即时通讯服务器,代码全部使用golang完成,功能包含好友之间一对一聊谈,群组聊天,支持单用户多设备同时在线,就像微信一样,当你同时使用两个设备登录账号时,两个设备可以都可以接收到消息,当你用一个设备发送消息时,另一个设备也能收到你发送的消息。目前完成了第一版,第一版不想做的太复杂庞大,但是好多细节逻辑都做了反复的推敲,其主要目的是先作出核心功能,不考略加缓存和MQ提高性能,所以还不是很完善,以后会逐渐完善。

    2 所用技术

    golang+mysql完成,web框架使用了gin(对gin进行了简单的封装),日志框架使用了zap,当然也自己写了一些小组件,例如TCP拆包粘包,唯一消息id生成器,数据库统一事务管理等。

    3 项目分层设计

    项目主要氛围两层,connect层和logic层,public包下放置了一些connect层和logic层公用的代码和一些基础库
    connect连接层,主要维护和客户端的tcp连接,所以connect是有状态的,connect包含了TCP拆包粘包,消息解码,客户端心跳等一些逻辑。
    logic逻辑层是无状态的,主要维护消息的转发逻辑,以及对外提供http接口,提供一些聊天系统基本的业务功能,例如,登录,注册,添加好友,删除好友,创建群组,添加人到群组,群组踢人等功能

    3 拆包粘包以及消息协议

    TCP拆包粘包是自己写的一个算法,其思想就是每次从系统缓冲读取数据流,放置到自己实现的一个buffer中,以后拆包粘包,还是消息解码都是在这个buffer完成,其目的是减少内存拷贝,提高性能。
    其中每一个TCP都遵循TLV格式(即类型,长度,值),第一部分由两个字节来标示数据类型,第二部分用两个字节来标示数据长度,第三部分则是真正要解码的数据。
    消息协议使用Google的Protocol Buffers,具体消息协议定制在/public/proto包下

    4 消息唯一id

    唯一消息id的主要作用是用来标示一次消息发送的完整流程,消息发送->消息投递->消息投递回执,用来线上排查线上问题。
    每一个消息有唯一的消息的id,由于消息发送频率比较高,所以性能就很重要,当时没有找到合适第三方库,所以就自己实现了一个,原理就是,每次从数据库中拿一个数据段,用完了再去数据库拿,当用完之后去从数据库拿的时候,会有一小会的阻塞,为了解决这个问题,就做成了异步的,就是保证内存中有n个可用的id,当id消耗掉小于n个时,就从数据库获取生成,当达到n个时,goroutine阻塞等待id被消耗,如此往复。

    5 主要逻辑

    client: 客户端
    connect:连接层
    logic:逻辑层
    mysql:存储层

    登录

    3496be2f9ee9d33e.jpg

    单发

    00d7e21cccc9050e.jpg

    群发

    7ee3ada2baf1dec0.jpg

    6 日志

    使用了zap的日志框架,下图展示了一次两个设备从登录,发一条消息,再到下线的一次流程的完整日志


    9f644dcd04b20287.jpg

    7 api文档

    https://documenter.getpostman.com/view/4164957/RzZ4q2hJ

    8 github

    https://github.com/alberliu/goim

    相关文章

      网友评论

        本文标题:golang写的即时通讯服务器

        本文链接:https://www.haomeiwen.com/subject/ljndtqtx.html