cellnet是一个组件化、高扩展性、高性能的开源服务器网络库。它的主要概念如下


队列
队列使用NewEventQueue创建,使用.StartLoop()开启队列事件处理循环,所有投递到队列中的函数回调会在队列自由的goroutine中被调用,逻辑在此时被处理

一般在main goroutine中调用queue.Wait阻塞等待队列结束。

队列在cellnet中使用cellnet.Queue接口, 底层由带缓冲的channel实现

端(Peer)
peer是客户端和服务端的封装
cellnet使用Acceptor接收多个连接,Acceptor是一种Peer(端),连接到Acceptor的Peer叫做Connector。

一个Peer拥有很多属性(名称,地址,队列),peer.NewGenericPeer函数封装了属性的设置过程。

peer.NewGenericPeer创建好的Peer不会产生任何socket操作,对于Acceptor来说,调用Acceptor的Start方法后,才会真正开始socket的侦听

使用如下代码创建一个接受器(Acceptor):

  queue := cellnet.NewEventQueue()

    // NewGenericPeer参数依次是: peer类型, peer名称(日志中方便查看), 侦听地址,事件队列
    peerIns := peer.NewGenericPeer("tcp.Acceptor", "server", "127.0.0.1:8801", queue)

    peerIns.Start()

Connector也是一种Peer,与Acceptor很很多类似的地方,因此创建过程也是类似的。

使用如下代码创建一个连接器(Connector):

queue := cellnet.NewEventQueue()

    peerIns := peer.NewGenericPeer("tcp.Connector", "client", "127.0.0.1:8801", queue)

    peerIns.Start("127.0.0.1:8801")

处理器(proc)
cellnet使用Processor处理消息的收发过程。

使用proc.BindProcessorHandler函数,将一个Peer绑定到某个Processor上,且设置用户消息处理回调。

下面代码尝试将peerIns的Peer,绑定"tcp.ltv"处理器,回调函数为func(ev cellnet.Event) { ... }

proc.BindProcessorHandler(peerIns, "tcp.ltv", func(ev cellnet.Event) {

    switch msg := ev.Message().(type) {
    // 有新的连接连到8801端口
    case *cellnet.SessionAccepted:
        log.Debugln("server accepted")
    // 有连接从8801端口断开
    case *cellnet.SessionClosed:
        log.Debugln("session closed: ", ev.Session().ID())
    // 收到某个连接的ChatREQ消息
    case *proto.ChatREQ:

        // 准备回应的消息
        ack := proto.ChatACK{
            Content: msg.Content,       // 聊天内容
            Id:      ev.Session().ID(), // 使用会话ID作为发送内容的ID
        }

        // 在Peer上查询SessionAccessor接口,并遍历Peer上的所有连接,并发送回应消息(即广播消息)
        p.(cellnet.SessionAccessor).VisitSession(func(ses cellnet.Session) bool {

            ses.Send(&ack)

            return true
        })

    }

})

callnet 通过这三种封装将网络连接和处理消息解耦开,下篇文章将要介绍callnet关于peer源码的解析,不同的协议(http,tcp, protobuf)都有对应的peer我将取其中(tcp)解析,其它的协议下的内容都差不多。


lyh1091106900
1 声望0 粉丝