-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
05 Zinx HeartBeat
Case Source Code : https://github.com/aceld/zinx-usage/tree/main/zinx_heartbeat
Zinx provides a heart beat mechanism, which is bi-directional. Both the server and the client can send heart beat messages to each other. The overall process of Zinx's heart beat mechanism is as follows:
The process of heartbeat detection as part of the above mechanism is as follows:
The parameters involved in the heartbeat detection process, such as interval
, HeartBeatMax
, MakeMsg
(to make heartbeat messages), OnRemoteNotAlive
(the callback logic for remote heartbeat timeout), HeartBeatMsgID
(the message ID for heartbeat messages), and Router
(the logic to handle heartbeat messages), can all be configured by developers. If developers have no customized requirements, Zinx also provides some default parameters for developers to use directly.
Parameter | Default Value |
---|---|
HeartBeatMsgID | 99999(integer) |
interval (detection interval / heartbeat message sending interval) | passed to StartHeartBeat method as 3 seconds |
HeartBeatMax (maximum heartbeat timeout) | 10s |
OnRemoteNotAlive (callback logic for remote heartbeat timeout) | |
func notAliveDefaultFunc(conn ziface.IConnection) |
|
package main
import (
"github.com/aceld/zinx/znet"
"time"
)
func main() {
// Create a new server instance
s := znet.NewServer()
// Start heartbeat detection with default parameters (check every 3 seconds)
s.StartHeartBeat(3 * time.Second)
// Start the server
s.Serve()
}
package main
import (
"github.com/aceld/zinx/znet"
"time"
)
func main() {
// Creating a client instance
client := znet.NewClient("127.0.0.1", 8999)
// Starting Heartbeat detection, checking every 3 seconds by default
client.StartHeartBeat(3 * time.Second)
// Starting the client
client.Start()
// Waiting for an interrupt signal to prevent the process from exiting
select {}
}
Zinx's heartbeat detection mechanism also provides the following options, which can be passed as custom parameters when creating a heartbeat detector using the method StartHeartBeatWithOption(interval time.Duration, option *ziface.HeartBeatOption):
// User-defined heartbeat message processing function
type HeartBeatMsgFunc func(IConnection) []byte
// User-defined processing function when the remote connection is not alive
type OnRemoteNotAlive func(IConnection)
type HeartBeatOption struct {
MakeMsg HeartBeatMsgFunc // User-defined heartbeat message processing function
OnRemoteNotAlive OnRemoteNotAlive // User-defined processing function when the remote connection is not alive
HeadBeatMsgID uint32 // User-defined heartbeat detection message ID
Router IRouter // User-defined heartbeat detection message business processing route
}
package main
import (
"fmt"
"github.com/aceld/zinx/ziface"
"github.com/aceld/zinx/znet"
"time"
)
// Custom heartbeat message processing method
func myHeartBeatMsg(conn ziface.IConnection) []byte {
return []byte("heartbeat, I am server, I am alive")
}
// Custom method to handle remote connection not alive
func myOnRemoteNotAlive(conn ziface.IConnection) {
fmt.Println("myOnRemoteNotAlive is Called, connID=", conn.GetConnID(), "remoteAddr = ", conn.RemoteAddr())
// Close the connection
conn.Stop()
}
// Custom router for heartbeat messages
type myHeartBeatRouter struct {
znet.BaseRouter
}
func (r *myHeartBeatRouter) Handle(request ziface.IRequest) {
// Business logic handling
fmt.Println("in MyHeartBeatRouter Handle, recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
}
func main() {
// Create a server
s := znet.NewServer()
myHeartBeatMsgID := 88888
// Start heartbeat detection with custom options
s.StartHeartBeatWithOption(1*time.Second, &ziface.HeartBeatOption{
MakeMsg: myHeartBeatMsg,
OnRemoteNotAlive: myOnRemoteNotAlive,
Router: &myHeartBeatRouter{},
HeadBeatMsgID: uint32(myHeartBeatMsgID),
})
// Start the server
s.Serve()
}
package main
import (
"fmt"
"github.com/aceld/zinx/ziface"
"github.com/aceld/zinx/znet"
"time"
)
// Custom heartbeat message processing function for the client
func myClientHeartBeatMsg(conn ziface.IConnection) []byte {
return []byte("heartbeat, I am Client, I am alive")
}
// Custom processing function when the remote connection is not alive
func myClientOnRemoteNotAlive(conn ziface.IConnection) {
fmt.Println("myClientOnRemoteNotAlive is Called, connID=", conn.GetConnID(), "remoteAddr = ", conn.RemoteAddr())
// Close the connection
conn.Stop()
}
// Custom heartbeat message processing method for the client
type myClientHeartBeatRouter struct {
znet.BaseRouter
}
func (r *myClientHeartBeatRouter) Handle(request ziface.IRequest) {
// Business logic processing
fmt.Println("in myClientHeartBeatRouter Handle, recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
}
func main() {
// Create a client handle using the Zinx API
client := znet.NewClient("127.0.0.1", 8999)
myHeartBeatMsgID := 88888
// Start heartbeat check
client.StartHeartBeatWithOption(3*time.Second, &ziface.HeartBeatOption{
MakeMsg: myClientHeartBeatMsg,
OnRemoteNotAlive: myClientOnRemoteNotAlive,
Router: &myClientHeartBeatRouter{},
HeadBeatMsgID: uint32(myHeartBeatMsgID),
})
// Start the client
client.Start()
select {}
}
It can be set through the zinx.json configuration file or passed through the Option when creating a Server.
conf/zinx.json
{
"Name":"Zinx Heartbeat",
"Host":"127.0.0.1",
"TcpPort":8999,
"MaxConn":3,
"WorkerPoolSize":10,
"LogDebugClose": true,
"HeartbeatMax": 10
}
Alternatively, the HeartBeatMax parameter can be passed through the creation of the Server:
func main() {
s := znet.NewUserConfServer(&zconf.Config{
HeartbeatMax: 20, // Set the maximum timeout interval (in seconds)
})
myHeartBeatMsgID := 88888
// Start heartbeating
s.StartHeartBeatWithOption(1*time.Second, &ziface.HeartBeatOption{
MakeMsg: myHeartBeatMsg,
OnRemoteNotAlive: myOnRemoteNotAlive,
Router: &myHeartBeatRouter{},
HeadBeatMsgID: uint32(myHeartBeatMsgID),
})
s.Serve()
}