- 9.5 使用Zinx-V0.9完成应用程序
9.5 使用Zinx-V0.9完成应用程序
好了,现在我们基本上已经将全部的连接管理的功能集成到Zinx中了,接下来就需要测试一下链接管理模块是否可以使用了。
写一个服务端:
Server.go
package mainimport ("fmt""zinx/ziface""zinx/znet")//ping test 自定义路由type PingRouter struct {znet.BaseRouter}//Ping Handlefunc (this *PingRouter) Handle(request ziface.IRequest) {fmt.Println("Call PingRouter Handle")//先读取客户端的数据,再回写ping...ping...pingfmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))err := request.GetConnection().SendBuffMsg(0, []byte("ping...ping...ping"))if err != nil {fmt.Println(err)}}type HelloZinxRouter struct {znet.BaseRouter}//HelloZinxRouter Handlefunc (this *HelloZinxRouter) Handle(request ziface.IRequest) {fmt.Println("Call HelloZinxRouter Handle")//先读取客户端的数据,再回写ping...ping...pingfmt.Println("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))err := request.GetConnection().SendBuffMsg(1, []byte("Hello Zinx Router V0.8"))if err != nil {fmt.Println(err)}}//创建连接的时候执行func DoConnectionBegin(conn ziface.IConnection) {fmt.Println("DoConnecionBegin is Called ... ")err := conn.SendMsg(2, []byte("DoConnection BEGIN..."))if err != nil {fmt.Println(err)}}//连接断开的时候执行func DoConnectionLost(conn ziface.IConnection) {fmt.Println("DoConneciotnLost is Called ... ")}func main() {//创建一个server句柄s := znet.NewServer()//注册链接hook回调函数s.SetOnConnStart(DoConnectionBegin)s.SetOnConnStop(DoConnectionLost)//配置路由s.AddRouter(0, &PingRouter{})s.AddRouter(1, &HelloZinxRouter{})//开启服务s.Serve()}
我们这里注册了两个Hook函数一个是链接初始化之后DoConnectionBegin()和链接停止之前DoConnectionLost()。
DoConnectionBegin()会发给客户端一个消息2的文本,并且在服务端打印一个调试信息"DoConnecionBegin is Called … "
DoConnectionLost()在服务端打印一个调试信息"DoConneciotnLost is Called … "
客户端:
Client.go
package mainimport ("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.8 Client0 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)}}
代码不变。
启动服务端
$go run Server.go
启动客户端
$go run Client.go
服务端结果:
$ go run Server.goAdd api msgId = 0Add api msgId = 1[START] Server name: zinx v-0.8 demoApp,listenner at IP: 127.0.0.1, Port 7777 is starting[Zinx] Version: V0.4, MaxConn: 3, MaxPacketSize: 4096start Zinx server zinx v-0.8 demoApp succ, now listenning...Worker ID = 9 is started.Worker ID = 5 is started.Worker ID = 6 is started.Worker ID = 7 is started.Worker ID = 8 is started.Worker ID = 1 is started.Worker ID = 0 is started.Worker ID = 2 is started.Worker ID = 3 is started.Worker ID = 4 is started.connection add to ConnManager successfully: conn num = 1---> CallOnConnStart....DoConnecionBegin is Called ...[Writer Goroutine is running][Reader Goroutine is running]Add ConnID= 0 request msgID= 0 to workerID= 0Call PingRouter Handlerecv from client : msgId= 0 , data= Zinx V0.8 Client0 Test MessageAdd ConnID= 0 request msgID= 0 to workerID= 0Call PingRouter Handlerecv from client : msgId= 0 , data= Zinx V0.8 Client0 Test MessageAdd ConnID= 0 request msgID= 0 to workerID= 0Call PingRouter Handlerecv from client : msgId= 0 , data= Zinx V0.8 Client0 Test MessageAdd ConnID= 0 request msgID= 0 to workerID= 0Call PingRouter Handlerecv from client : msgId= 0 , data= Zinx V0.8 Client0 Test MessageAdd ConnID= 0 request msgID= 0 to workerID= 0Call PingRouter Handlerecv from client : msgId= 0 , data= Zinx V0.8 Client0 Test Messageread msg head error read tcp4 127.0.0.1:7777->127.0.0.1:49510: read: connection reset by peerConn Stop()...ConnID = 0---> CallOnConnStop....DoConneciotnLost is Called ...connection Remove ConnID= 0 successfully: conn num = 0127.0.0.1:49510 [conn Reader exit!]127.0.0.1:49510 [conn Writer exit!]
客户端结果:
$ go run Client0.goClient Test ... start==> Recv Msg: ID= 2 , len= 21 , data= DoConnection BEGIN...==> Recv Msg: ID= 0 , len= 18 , data= ping...ping...ping==> Recv Msg: ID= 0 , len= 18 , data= ping...ping...ping==> Recv Msg: ID= 0 , len= 18 , data= ping...ping...ping==> Recv Msg: ID= 0 , len= 18 , data= ping...ping...ping^Csignal: interrupt
客户端创建成功,回调Hook已经执行,并且Conn被添加到ConnManager 中, conn num = 1,
当我们手动CTRL+C 关闭客户端的时候, 服务器ConnManager已经成功将Conn摘掉,conn num = 0.
同时服务端也打印出 conn停止之后的回调信息。
