现在我们可以基于Zinx框架完成发送msg功能的测试用例了。

    Server.go

    1. package main
    2. import (
    3. "fmt"
    4. "zinx/ziface"
    5. "zinx/znet"
    6. )
    7. //ping test 自定义路由
    8. type PingRouter struct {
    9. znet.BaseRouter
    10. }
    11. //Test Handle
    12. func (this *PingRouter) Handle(request ziface.IRequest) {
    13. fmt.Println("Call PingRouter Handle")
    14. //先读取客户端的数据,再回写ping...ping...ping
    15. fmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
    16. //回写数据
    17. err := request.GetConnection().SendMsg(1, []byte("ping...ping...ping"))
    18. if err != nil {
    19. fmt.Println(err)
    20. }
    21. }
    22. func main() {
    23. //创建一个server句柄
    24. s := znet.NewServer()
    25. //配置路由
    26. s.AddRouter(&PingRouter{})
    27. //开启服务
    28. s.Serve()
    29. }

    当前Server端是先把客户端发送来Msg解析,然后返回一个MsgId为1的消息,消息内容是”ping…ping…ping”

    Client.go

    package main
    
    import (
        "fmt"
        "io"
        "net"
        "time"
        "zinx/znet"
    )
    
    /*
        模拟客户端
     */
    func main() {
    
        fmt.Println("Client Test ... start")
        //3秒之后发起测试请求,给服务端开启服务的机会
        time.Sleep(3 * time.Second)
    
        conn,err := net.Dial("tcp", "127.0.0.1:7777")
        if err != nil {
            fmt.Println("client start err, exit!")
            return
        }
    
        for {
            //发封包message消息
            dp := znet.NewDataPack()
            msg, _ := dp.Pack(znet.NewMsgPackage(0,[]byte("Zinx V0.5 Client Test Message")))
            _, err := conn.Write(msg)
            if err !=nil {
                fmt.Println("write error err ", err)
                return
            }
    
            //先读出流中的head部分
            headData := make([]byte, dp.GetHeadLen())
            _, err = io.ReadFull(conn, headData) //ReadFull 会把msg填充满为止
            if err != nil {
                fmt.Println("read head error")
                break
            }
            //将headData字节流 拆包到msg中
            msgHead, err := dp.Unpack(headData)
            if err != nil {
                fmt.Println("server unpack err:", err)
                return
            }
    
            if msgHead.GetDataLen() > 0 {
                //msg 是有data数据的,需要再次读取data数据
                msg := msgHead.(*znet.Message)
                msg.Data = make([]byte, msg.GetDataLen())
    
                //根据dataLen从io中读取字节流
                _, err := io.ReadFull(conn, msg.Data)
                if err != nil {
                    fmt.Println("server unpack data err:", err)
                    return
                }
    
                fmt.Println("==> Recv Msg: ID=", msg.Id, ", len=", msg.DataLen, ", data=", string(msg.Data))
            }
    
            time.Sleep(1*time.Second)
        }
    }
    

    这里Client客户端,模拟了一个MsgId为0的”Zinx V0.5 Client Test Message”消息,然后把服务端返回的数据打印出来。

    我们分别在两个终端运行

    $go run Server.go
    
    $go run Client.go
    

    服务端结果:

    $ go run Server.go 
    Add Router succ! 
    [START] Server name: zinx v-0.5 demoApp,listenner at IP: 127.0.0.1, Port 7777 is starting
    [Zinx] Version: V0.4, MaxConn: 3, MaxPacketSize: 4096
    start Zinx server   zinx v-0.5 demoApp  succ, now listenning...
    Reader Goroutine is  running
    Call PingRouter Handle
    recv from client : msgId= 0 , data= Zinx V0.5 Client Test Message
    Call PingRouter Handle
    recv from client : msgId= 0 , data= Zinx V0.5 Client Test Message
    Call PingRouter Handle
    recv from client : msgId= 0 , data= Zinx V0.5 Client Test Message
    ...
    

    客户端结果:

    $ go run Client.go 
    Client Test ... start
    ==> Recv Msg: ID= 1 , len= 18 , data= ping...ping...ping
    ==> Recv Msg: ID= 1 , len= 18 , data= ping...ping...ping
    ==> Recv Msg: ID= 1 , len= 18 , data= ping...ping...ping
    ...
    

    好了,我们的Zinx已经成功的集成消息的封装功能了,这样我们就有Zinx的通信的基本协议标准了。