Diarkis servers (pods) can talk to each other to execute certain operations on other servers and even perform request and response style communications.
We recommend using github.com/Diarkis/diarkis/datacapsule for handling transported data (response data of mesh communications)
Request And Response Style Communication
This type of communication is when one server node sends a request to another server node expecting a response from it.
Request Receiver
// import "github.com/Diarkis/diarkis/datacapsule" // This is used to handle to transported data
// cmdID is a unique ID for the internal command similar to HTTP URL
mesh.Command(cmdID, handleInternalCommand)
func handleInternalCommmand(req map[string]interface{}) (map[string]interface{}, error) {
// request parameters
question := mesh.GetInt(req, "question")
userMessage := mesh.GetBytes(req, "message")
messageData := make([]byte, 0)
switch question {
case 1:
messageData = CreateMessageDataForCaseOne(userMessage)
case 2:
messageData = CreateMessageDataForCaseTwo(userMessage)
default:
return nil, errors.New("Invalid question")
}
cp := datacapsule.NewCapsule()
cp.SetAsBytes("messageData", messageData)
// returned value of cp.Export() will be sent as a response data
return cp.Export(), nil
}
Request Sender
requestParams := make(map[string]interface{})
requestParams["question"] = 1
requestParams["message"] = userMessage
// cmdID is a unique ID for the internal command similar to HTTP URL
mesh.SendRequest(cmdID, receiverAddr, requestParams, func(err error, res map[string]interface{}) {
if err != nil {
// handle the error here
return
}
responseCapsule := datacapsule.NewCapsule()
responseData, err := responseCapsule.Import(res)
if err != nil {
// handle error here
}
logger.Debug("We have the response %v - error? %v", responseData.GetAsBytes("messageData"))
})
Send An Internal Message To Multiple Server Nodes
This style of internal communication does not expect remote server nodes to send a response.
Receiver
mesh.Command(commandID, handleCommand)
func handleCommand(req map[string]interface{}) (error, map[string]interface{}) {
message := mesh.GetString(req, "message")
id := mesh.GetUint32("id")
timestamp := GetInt64("timestamp")
logger.Debug("Do something with %s of %v and %v", message, id, timestamp)
// We do not send a response
return nil, nil
}
Sender
// All UDP server node addresses
udpNodes := mesh.GetNodeAddressesByType(udp.Type)
// Message data to be delivered
data := make(map[string]interface{})
data["message"] = message
data["id"] = messageID // messageID is uint32
Data["timestamp"] = timestamp // timestamp in milliseconds is int64
// deliveryLimit is the number of server nodes to send the message to simultaneously
deliveryLimit := 2
// This is a reliable message delivery to guarantee the delivery of the message to all server nodes
mesh.SendMany(commandID, udpNodes, data, deliveryLimit)
/// This is an unreliable message delivery: faster and cheaper, but not reliable
mesh.USendMany(commandID, udpNodes, data, deliveryLimit)
How To Check Online/Offline Status Of A Server Node
A Diarkis server node may go offline when a server node receives SIGTERM.
When a server node is offline, it stops receiving new client connections, and Room and Group will not allow new rooms/groups to be created.
The connected clients may continue with the communications as normal but are encouraged to reconnect to another node by receiving OnOffline event notifications.
// Check to see if a specific server node is online or not
online := mesh.IsNodeOnline(nodeMeshAddr)
// Check to see if itself is online or not
amIOnline := mesh.IsMyNodeOnline()