Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 1.3k
02 Zinx Router
Case Source Code : https://github.com/aceld/zinx-usage/tree/main/zinx_router
Zinx supports setting different routing and callback business modes for binary message bodies with different MsgID. The interface definition of IRouter is as follows:
package ziface
/* The router interface, where the router is the processing business method customized by the framework user for the link. The IRequest in the router contains the link information of the link and the request data information of the link.*/typeIRouterinterface {
PreHandle(requestIRequest) // The hook method before processing conn businessHandle(requestIRequest) // The method for processing conn businessPostHandle(requestIRequest) // The hook method after processing conn business
}The overall business invocation chain is PreHandle()-->Handle()-->PostHandle(). Developers can implement specific Router instances and bind routes to Server/Client instances through the AddRouter() method. An example of specific application instance is as follows.
The code directory structure is as follows:
└── router-usage
├── client
│ ├── main.go
│ └── router
│ └── pong.go
├── common
│ └── proto.go
└── server
├── main.go
└── router
└── ping.go
server/main.go
package main
import (
"github.com/aceld/zinx/znet""zinx-usage/zinx_router/router-usage/server/router"
)
const (
MsgIdPing=1
)
funcmain() {
//1 Create a server services:=znet.NewServer()
//2 Configure routess.AddRouter(MsgIdPing, &router.PingRouter{})
//3 Start the services.Serve()
}common/proto.go
package common
const (
MsgIdPing=1MsgIdPong=2
)server/router/ping.go
package router
import (
"fmt""github.com/aceld/zinx/ziface""github.com/aceld/zinx/znet""zinx-usage/zinx_router/router-usage/common"
)
// PingRouter MsgIdPing routetypePingRouterstruct {
znet.BaseRouter
}
//Ping Handle method for MsgIdPing routefunc (r*PingRouter) PreHandle(request ziface.IRequest) {
//Read client datafmt.Println("PreHandle: recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
}
//Ping Handle method for MsgIdPing routefunc (r*PingRouter) Handle(request ziface.IRequest) {
//Read client datafmt.Println("Handle: recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
request.GetConnection().SendMsg(common.MsgIdPong, []byte("pong...pong...pong...[FromServer]"))
}
//Ping Handle method for MsgIdPing routefunc (r*PingRouter) PostHandle(request ziface.IRequest) {
//Read client datafmt.Println("PostHandle: recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
}When the Server receives the MsgIdPing message, it will call the PreHandle, Handle, and PostHandle methods in turn. Among them, Handle sends the MsgIdPong message back to the client.
Clients can also set up message callback routing using the Router. The Client still provides the AddRouter() method. A specific Client example is shown below:
client/main.go
package main
import (
"fmt""github.com/aceld/zinx/ziface""github.com/aceld/zinx/znet""time""zinx-usage/zinx_router/router-usage/client/router""zinx-usage/zinx_router/router-usage/common"
)
// Custom business logic for the clientfuncpingLoop(conn ziface.IConnection) {
for {
err:=conn.SendMsg(common.MsgIdPing, []byte("Ping...Ping...Ping...[FromClient]"))
iferr!=nil {
fmt.Println(err)
break
}
time.Sleep(1*time.Second)
}
}
// Executed when creating a connectionfunconClientStart(conn ziface.IConnection) {
fmt.Println("onClientStart is Called ... ")
gopingLoop(conn)
}
funcmain() {
// Create the Clientclient:=znet.NewClient("127.0.0.1", 8999)
// Set the hook function after the connection is establishedclient.SetOnConnStart(onClientStart)
// Set the message reading routingclient.AddRouter(common.MsgIdPong, &router.PongRouter{})
// Start the clientclient.Start()
// Prevent process exit, wait for interrupt signalselect {}
}The router for MsgIdPong messages in the Client is defined as follows:
client/router/pong.go
package router
import (
"fmt""github.com/aceld/zinx/ziface""github.com/aceld/zinx/znet"
)
// PongRouter is the router for MsgIdPongtypePongRouterstruct {
znet.BaseRouter
}
// Handle is the router for MsgIdPongfunc (r*PongRouter) Handle(request ziface.IRequest) {
// Read the data from the clientfmt.Println("Handle: recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
}After starting the Server and the Client in two terminals, the following output is obtained:
$ go run main.go PreHandle: recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
Handle: recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
PostHandle: recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
PreHandle: recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
Handle: recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
PostHandle: recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
PreHandle: recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
Handle: recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
PostHandle: recv from client : msgId= 1 , data= Ping...Ping...Ping...[FromClient]
...$ go run main.go onClientStart is Called ... Handle: recv from client : msgId= 2 , data= pong...pong...pong...[FromServer]
Handle: recv from client : msgId= 2 , data= pong...pong...pong...[FromServer]
Handle: recv from client : msgId= 2 , data= pong...pong...pong...[FromServer]
Handle: recv from client : msgId= 2 , data= pong...pong...pong...[FromServer]
Handle: recv from client : msgId= 2 , data= pong...pong...pong...[FromServer]
...The above example is the basic routing configuration mode of Zinx.
In the Router call, Abort() or Goto() can be used in the callback Handler() to terminate or jump to the corresponding callback node.
Terminate the link.
Server-side code in router-goto/server.go:
package main
import (
"fmt""github.com/aceld/zinx/ziface""github.com/aceld/zinx/znet"
)
typeTestRouterstruct {
znet.BaseRouter
}
func (t*TestRouter) PreHandle(req ziface.IRequest) {
fmt.Println("--> Call PreHandle")
}
func (t*TestRouter) Handle(req ziface.IRequest) {
fmt.Println("--> Call Handle")
//Terminate the route link callreq.Abort()
}
func (t*TestRouter) PostHandle(req ziface.IRequest) {
fmt.Println("--> Call PostHandle")
}
funcmain() {
s:=znet.NewServer()
s.AddRouter(1, &TestRouter{})
s.Serve()
}Client-side code in router-goto/client.go:
package main
import (
"fmt""github.com/aceld/zinx/ziface""github.com/aceld/zinx/znet""time"
)
//Customize client businessfuncpingLoop(conn ziface.IConnection) {
for {
err:=conn.SendMsg(1, []byte("Ping...Ping...Ping...[FromClient]"))
iferr!=nil {
fmt.Println(err)
break
}
time.Sleep(1*time.Second)
}
}
//Execute when creating a connectionfunconClientStart(conn ziface.IConnection) {
fmt.Println("onClientStart is Called ... ")
gopingLoop(conn)
}
funcmain() {
//Create a Clientclient:=znet.NewClient("127.0.0.1", 8999)
//Set the hook function after the connection is establishedclient.SetOnConnStart(onClientStart)
//Start the clientclient.Start()
//Prevent process exit and wait for interrupt signalselect {}
}Run the server and client, and observe the printed information in the server terminal:
$ go run server.go --> Call PreHandle
--> Call Handle
--> Call PreHandle
--> Call Handle
--> Call PreHandle
--> Call Handle
--> Call PreHandle
--> Call HandleThe link only executed PreHandle() --> Handle() and terminated without executing PostHandle().
Note: Be careful, it will cause loop calling Jump to the link, the jump node provides three macros as follows:
znet.PRE_HANDLE
znet.HANDLE
znet.POST_HANDLEServer-side code:
package main
import (
"fmt""github.com/aceld/zinx/ziface""github.com/aceld/zinx/znet"
)
typeTestRouterstruct {
znet.BaseRouter
}
func (t*TestRouter) PreHandle(req ziface.IRequest) {
fmt.Println("--> Call PreHandle")
//Jumpreq.Goto(znet.POST_HANDLE)
}
func (t*TestRouter) Handle(req ziface.IRequest) {
fmt.Println("--> Call Handle")
}
func (t*TestRouter) PostHandle(req ziface.IRequest) {
fmt.Println("--> Call PostHandle")
}
funcmain() {
s:=znet.NewServer()
s.AddRouter(1, &TestRouter{})
s.Serve()
}Run the server and client, and observe the print information in the server terminal:
$go run server.go
--> Call PreHandle
--> Call PostHandle
--> Call PreHandle
--> Call PostHandle
--> Call PreHandle
--> Call PostHandleThe result is that it jumps directly from PreHandle() to PostHandle().