Diarkis サーバ間通信 - Mesh Package

Diarkis のサーバ(ポッド)は、互いに通信することで他のサーバで特定の操作を実行したり、リクエスト&レスポンス形式の通信を行うことができます。

サーバ間でやりとりされるデータのハンドリングには github.com/Diarkis/dairkis/datacapsule を使うことをお勧めしています。

リクエスト&レスポンススタイルの通信

以下は、あるサーバーノードが他のサーバーノードにリクエストを送信し、そのレスポンス受けるタイプの通信です。

リクエスト受信

// 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
}

リクエスト送信

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"))
})

複数のサーバノードへのメッセージの送信

以下は、リモートのサーバノードが応答を送信することを期待しない通信です。

受信者

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
}

送信者

// 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)

サーバノードのオンライン/オフライン状態を確認する方法

サーバノードが SIGTERM を受信すると、Diarkis のサーバノードはオフラインモードになります。

サーバノードがオフラインモードになると、クライアントの新規接続を受け付けなくなり、 Room や Group の新規作成ができなくなります。

接続されたクライアントは通常通り通信を続けることができますが、OnOffline イベントが発生しますので、別のノードに再接続してください。

// 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()