UDPサーバー

UDPサーバーは、Diarkisの3つのリアルタイム・コミュニケーション・サーバーのうちの1つで、アプリケーションにカスタムの「コマンド」を実装することができます。コマンドとは、クライアントから送信され、サーバーで処理されるフォーマットされたパケットのことです。コマンドを利用し、Diarkisのサーバークラスターがクライアントと対話します。

servers/udp/main.go
package main

import (
 "fmt"
 "github.com/Diarkis/diarkis"
 "your/project/cmds"
 "github.com/Diarkis/diarkis/log"
 "github.com/Diarkis/diarkis/mesh"
 "github.com/Diarkis/diarkis/server"
 "os"
)

func main() {
 rootpath, err := os.Getwd()
 if err != nil {
  panic(err)
 }
 log.Setup(fmt.Sprintf("%s/configs/shared/log.json", rootpath))
    // Sets up the internal communication network
 mesh.Setup(fmt.Sprintf("%s/configs/shared/mesh.json", rootpath))
    // Sets up the server as TCP server
 server.SetupAsTCPServer(fmt.Sprintf("%s/configs/udp/main.json", rootpath))
 cmds.Setup(rootpath)
    // Exposes all commands including built-in commands and custom commands
 cmds.ExposeServer()
 diarkis.Start()
}

UDP サーバの設定

 

connectionTTL

10

接続のTTL(秒)。デフォルトは10秒です

address

“127.0.0.1”

バインドするUDPサーバーのアドレス

nic

“eth0”

UDPサーバーのバインドされたアドレスを取得するネットワークインターフェースの名前

port

“7100”

UDPサーバーがバインドするためのポート。UDPサーバーは、指定されたポートから始まる利用可能なポートを自動的に探します

enableP2P

true

trueに設定すると、クライアントはP2P用に自分のパブリックアドレスを取得することができます。

enableEncryption

true

falseに設定すると、パケットの暗号化と復号化が無効になります。HTTPも同様の設定をする必要があります。

※ クラウド環境では、addressはプライベートIPアドレスとし、環境変数DIARKIS_CLOUD_ENVを併用してください。

環境変数の設定

Diarkisには、コンフィグレーションの環境変数による自動置換機能があります。
設定の中にあらかじめ定められた値を追加すると、その値は環境変数で置き換えられます。

Example:

環境変数: DIARKIS_TEST=127.0.0.1

設定ファイル: “address”: “{$DIARKIS_TEST}”

「アドレス」の値は「127.0.0.1」になります。

サーバのシャットダウン時の処理

Diarkisクラスターのサーバは、シャットダウン時に、接続されたクライアントが他のサーバに再接続するのを待ちます。サーバは、SIGTERMを受信すると「オフライン」になります。オフラインモードになると、サーバはシャットダウンの準備を開始します。

接続されているすべてのクライアントは、オフライン通知を受け取り、「OnOffline」イベントを発生させます。オフラインモードのサーバは、新しいクライアントを受け入れず、新しいルームやグループの作成を許可しません。オフラインのサーバは、接続されているすべてのクライアントがサーバから切断されるのを待ちますが、サーバにはタイムアウトがあり、タイムアウトが切れると、クライアントを待たずにシャットダウンします。

デフォルトのタイムアウトは10秒です。

環境変数でデフォルトのタイムアウトを変更する方法:

# This will change the server shutdown timeout to 60 seconds
DIARKIS_SHUTDOWN_TIMEOUT=60

UDPサーバのカスタムコマンドの書き方

コマンドとは、クライアントからDiarkisサーバクラスタに送信され、サーバによって処理されるフォーマットされたパケットのことです。これにより、Diarkisはクライアントと通信します。コマンドの実装インターフェースは、すべてのネットワークプロトコルで統一されています。

cmds/custom/main.go

package customcmds

import (
 "github.com/Diarkis/diarkis/log"
 "github.com/Diarkis/diarkis/server"
 "github.com/Diarkis/diarkis/user"
)

const customVer = 2
const helloCmdID = 10
const pushCmdID = 11

var logger = log.New("CUSTOM")
// this is called in cmds/main.go
func Expose() {
 server.HandleCommand(customVer, helloCmdID, helloCmd)
 server.HandleCommand(customVer, helloCmdID, afterHelloCmd)
 server.HandleCommand(customVer, pushCmdID, pushCmd)
}

func helloCmd(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)) {
 // payload is the byte array sent from the client
 logger.Debug("Payload %#v SID:%s - UID:%s", payload, userData.SID, userData.ID)
 // if this is executed as UDP, reliable = true means sending the packet as an RUDP packet
 reliable := true
 // we send a response back to the client with the byte array sent from the client
 userData.ServerRespond(payload, ver, cmd, server.Ok, reliable)
 // move on to the next command handler if there is any
 next(nil)
}

func afterHelloCmd(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)) {
 logger.Debug("This is executed after Hello command has been handled")
 next(nil)
}

func pushCmd(ver uint8, cmd uint16, payload []byte, userData *user.User, next func(error)) {
 // payload is the byte array sent from the client
 logger.Debug("Payload %#v SID:%s - UID:%s", payload, userData.SID, userData.ID)
 // if this is executed as UDP, reliable = true means sending the packet as an RUDP packet
 reliable := true
 // we send a push packet to the client that sent the data to this command
 userData.ServerPush(ver, cmd, payload, reliable)
 // move on to the next command handler if there is any
 next(nil)
}

ServerRespondとServerPushの違い

Diarkisクライアントには、2種類のパケット受信イベントがあります。レスポンスとプッシュです。

レスポンスパケットは、HTTPレスポンスに似た「ステータス」を持っています。これは通常、コマンド実行の応答として使用されます。PushはResponseと異なり、「ステータス」を持ちません。 

プッシュパケットは通常、クライアントが要求しなくてもDiarkisサーバクラスターから送信されます。

プッシュパケットの例としては、部屋からのブロードキャストメッセージなどがあります。

Response:

// payloadByteArray is the message byte array to be sent to the client
// cmdVer is the version of the response 0 and 1 is reserved by Diarkis internal.
// cmdID is the command ID of the response.
// response status: OK = 1, BAD = 4, and ERROR = 5
// reliable is used for UDP server only and if this is set to true, the response becomes RUDP
userData.ServerRespond(payloadByteArray, cmdVer, cmdID, status, reliable)

Push:

// payloadByteArray is the message byte array to be sent to the client
// cmdVer is the version of the response 0 and 1 is reserved by Diarkis internal.
// cmdID is the command ID of the response.
// reliable is used for UDP server only and if this is set to true, the response becomes RUDP
userData.ServerRespond(cmdVer, cmdID, payloadByteArray, reliable)