package znet import ( "fmt" "go-study/zinx/ziface" "net" "testing" "time" ) type PingRouter struct { BaseRouter } func (pr *PingRouter) Handle(request ziface.IRequest) { fmt.Println("Call PingRouter Handle") // 先读取客户端的数据,再回写ping...ping...ping fmt.Println("recv from client: msgID=", request.GetMsgID(), ", data=", string(request.GetData())) // 回写数据 err := request.GetConnection().SendMsg(0, []byte("ping...ping...ping\n")) if err != nil { fmt.Println("call back ping error:", err.Error()) } } type HelloZinxRouter struct { BaseRouter } func (h *HelloZinxRouter) Handle(request ziface.IRequest) { fmt.Println("Call HelloZinxRouter Handle") // 先读取客户端的数据,再回写ping...ping...ping fmt.Println("recv from client: msgID=", request.GetMsgID(), ", data=", string(request.GetData())) // 回写数据 err := request.GetConnection().SendMsg(1, []byte("Hello Zinx Router V0.6\n")) if err != nil { fmt.Println("call back HelloZinx error:", err.Error()) } } // DoConnectionBegin 创建连接之后执行的钩子函数 func DoConnectionBegin(conn ziface.IConnection) { fmt.Println("DoConnectionBegin is Called ... ") if err := conn.SendMsg(2, []byte("DoConnection BEGIN")); err != nil { fmt.Println("DoConnectionBegin error:", err) } } // DoConnectionLost 连接断开之前执行的钩子函数 func DoConnectionLost(conn ziface.IConnection) { fmt.Println("DoConnectionLost is Called ... ") fmt.Println("conn ID =", conn.GetConnID(), " is lost...") } // ClientTest0 模拟客户端0 func ClientTest0() { fmt.Println("Client Test... start") // 3s 之后发起测试请求,给服务器端开启服务的机会 time.Sleep(3 * time.Second) conn, err := net.Dial("tcp", "127.0.0.1:7777") if err != nil { fmt.Println("client dial err:", err) return } for { // 发送封包数据 dp := NewDataPack() msg, _ := dp.Pack(NewMsgPackage(0, []byte("Zinx V0.6 Client1 Test Message"))) if _, err := conn.Write(msg); err != nil { fmt.Println("write error:", err) return } // 服务器回复一个数据,先读出流中的 head 部分 headData := make([]byte, dp.GetHeadLen()) if _, err := conn.Read(headData); err != nil { fmt.Println("read head error:", err) break } // 拆包,得到 msgID 和 dataLen 放在 msg 中 msgHead, err := dp.Unpack(headData) if err != nil { fmt.Println("unpack head error:", err) return } if msgHead.GetDataLen() > 0 { // msg 是有数据的,需要再次读取 dataLen 个字节的数据 msg := msgHead.(*Message) msg.data = make([]byte, msg.GetDataLen()) // 根据 dataLen 的长度再次从io中读取 if _, err := conn.Read(msg.data); err != nil { fmt.Println("read msg data error:", err) return } fmt.Println("==> Recv Server Msg: ID=", msg.GetMsgID(), ", len=", msg.GetDataLen(), ", data=", string(msg.GetData())) } time.Sleep(1 * time.Second) } } // ClientTest1 模拟客户端1 func ClientTest1() { fmt.Println("Client Test... start") // 3s 之后发起测试请求,给服务器端开启服务的机会 time.Sleep(3 * time.Second) conn, err := net.Dial("tcp", "127.0.0.1:7777") if err != nil { fmt.Println("client dial err:", err) return } for { // 发送封包数据 dp := NewDataPack() msg, _ := dp.Pack(NewMsgPackage(1, []byte("Zinx V0.6 Client2 Test Message"))) if _, err := conn.Write(msg); err != nil { fmt.Println("write error:", err) return } // 服务器回复一个数据,先读出流中的 head 部分 headData := make([]byte, dp.GetHeadLen()) if _, err := conn.Read(headData); err != nil { fmt.Println("read head error:", err) break } // 拆包,得到 msgID 和 dataLen 放在 msg 中 msgHead, err := dp.Unpack(headData) if err != nil { fmt.Println("unpack head error:", err) return } if msgHead.GetDataLen() > 0 { // msg 是有数据的,需要再次读取 dataLen 个字节的数据 msg := msgHead.(*Message) msg.data = make([]byte, msg.GetDataLen()) // 根据 dataLen 的长度再次从io中读取 if _, err := conn.Read(msg.data); err != nil { fmt.Println("read msg data error:", err) return } fmt.Println("==> Recv Server Msg: ID=", msg.GetMsgID(), ", len=", msg.GetDataLen(), ", data=", string(msg.GetData())) } time.Sleep(1 * time.Second) } } // TestServer 服务器端测试 func TestServer(t *testing.T) { // 创建一个 Server 句柄 s := NewServer() // 设置连接创建和销毁的钩子函数 s.SetOnConnStart(DoConnectionBegin) s.SetOnConnStop(DoConnectionLost) // 给当前 Zinx 框架添加自定义的 Router s.AddRouter(0, &PingRouter{}) s.AddRouter(1, &HelloZinxRouter{}) // 启动客户端测试0 go ClientTest0() // 启动客户端测试1 go ClientTest1() // 启动服务器 s.Serve() }