专业IM即时通讯软件开发,值得信赖!

goim源码阅读

未分类 云聊IM 496℃

goim源码架构网上到处都是,就不画蛇添足了.

需要看懂的有几点:

一、comet相关:

comet 有几个链接? 与客户端直连的链接,与后端直连的链接 怎么处理?普通链接与websocket链接之间关系及设计方式?

1、与后端服务的连接

连接方面的管理,通过一个server:type Server struct {    c *conf.Config    round *Round // accept round store    buckets []*Bucket // subkey bucket    bucketIdx uint32
    serverID string    rpcClient logic.LogicClient}1)有一个round 看起来是管理读写pool 以及timer的。有待分析

2)有多个 Bucket 一个Bucket会有多个room 一个room有多个 Channel

而每个Channel里面 都有个 signal chan *grpc.Proto 看起来其与后面的服务通信都是通过grpc来实现的.有个Ring(似乎是管理 接受到的proto buffer的一个buff环)

3)rpcClient 看起来是一个与logic服务通信的grpc通信通道..与本目录下的grpc/server文件不是一回事。

 2、与客户端的链接管理:

建立tcp accept那套,没理解的是 开cpu个数的协程去accept??有必要??

accept成功的链接,开个协程处理。。

然后对链接鉴权,白名单处理 过了再开个dispatch处理协议。。当前协程就处理心跳这些东东…

没弄懂为啥要用grpc来做与客户端的通信协议解析???

tcp数据接收发送有点骚。搞个bufio。把accept到的socket作为io.writer绑定上。然后读写数据就是对bufio的。write,copy了。。这个操作骚

代码设计上讲,这些操作都包装成Server类的函数和局部变量去操作..这个操作有点骚..

然后。。特么的又搞了个server_websocket链接。。。把前面写的 建立tcp accept另走了一遍??为啥??不能重用一个链接吗???这个设计让人看不懂

二、job相关:

这块实现比较简单.

1、与kafka那边的链接

kafka的 cluster 用的是 ‘github.com/bsm/sarama-cluster’

同时弄了个Room队列…

建立好kafka之间的关系后 Consume 监听kafka那边来的通知。监听到后协议解析。各种push..发广播的广播 发客户端的发客户端..

2、与comet那边的链接:

建立起一组与comet的链接。。发广播 以及推消息的时候 就用这里的这些链接..

三、logic相关:

dao貌似封装了与kafka及redis的操作

kafka模块 用的是’gopkg.in/Shopify/sarama.v1′

redis模块 用的是’github.com/gomodule/redigo/redis’

http 用的是’github.com/gin-gonic/gin’

网络流程是通过grpc串接起来的..往grpc注册了 LogicServer。。然后就处理对应的协议及函数请求。。这块代码好像没啥好读的..

貌似我还是没搞懂 他这个消息是怎么转发的。。关于撸个简单的分布式服务器这块 感觉这代码还是够用的了

四、proto-go相关:

proto文件是否类似于.tars文件,有专门工具自动生成文件?

五、router:

这货貌似把router迁移到redis中 但没更新文档。。卧槽。。

另外网络架构很多事都通过grpc和他们自己的注册服务 ‘github.com/bilibili/discovery/naming’ 封装掉了。。没啥好玩的

其它代码细节摘录:

flag.Parse()                 //flag解析
rand.Seed(time.Now().UTC().UnixNano())   //设置随机种子
runtime.GOMAXPROCS(runtime.NumCPU())  //设置cpu核数
 
main.go的exit的信号处理: 这个写的也挺有意思
{
    c := make(chan os.Signal, 1)
    signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
    for {
        s := <-c
        log.Infof("goim-job get a signal %s", s.String())
        switch s {
        case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
            j.Close()    //功能关闭..
            log.Infof("goim-job [version: %s] exit", ver)
            log.Flush()
            return
        case syscall.SIGHUP:
        default:
            return
        }
    }
}

本文转自:https://www.cnblogs.com/yylingyao/p/11079185.html

喜欢 (29)
仿微信聊天软件开发
点击这里给我发消息