WebSocketサーバ

WebSocketサーバは、Diarkisの3つのリアルタイム通信サーバーのうち、Web技術に特化したもので、アプリケーションにカスタムの「コマンド」を実装することができます。コマンドとは、クライアントから送信され、サーバで処理されるフォーマットされたパケットです。これは、Diarkisのサーバクラスタがクライアントと対話する方法です。

cmds/servers/ws/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))
  mesh.Setup(fmt.Sprintf("%s/configs/shared/mesh.json", rootpath))
  server.SetupAsWebSocketServer(fmt.Sprintf("%s/configs/ws/main.json", rootpath))
  cmds.Setup(rootpath)
  cmds.ExposeServer()
  diarkis.Start()
}

WebSocket サーバの設定

address

“127.0.0.1”

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

nic

“eth0”

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

port

“7100”

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

uri

“/ws”

クライアントからのWebSocket通信用のURIです

readInterval

400

受信パケットの読み取り間隔をミリ秒単位で指定します

ttl

30

接続TTL(秒)

※ クラウド環境の場合、addressはプライベートIPアドレスとし、環境変数DIARKIS_CLOUD_ENVを併用します

環境変数の設定

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

例:

環境変数: DIARKIS_TEST=127.0.0.1

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

「address」の値は「127.0.0.1」になります

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

コマンドとは、クライアントから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.HandleWSCommand(customVer, helloCmdID, helloCmd)
 server.HandleWSCommand(customVer, helloCmdID, afterHelloCmd)
 server.HandleWSCommand(customVer, pushCmdID, pushCmd)
}

func helloCmd(ver, cmd float64, data map[string]interface{}, userData *user.User, next func(error)) {
 // data is the parsed JSON data sent from the client
 logger.Debug("Data %#v SID:%s - UID:%s", data, userData.SID, userData.ID)
 // we send a response back to the client with the same data map sent from the client
 userData.ServerRespond(data, uint8(ver), uint16(cmd), server.Ok, true)
 // move on to the next command handler if there is any
 next(nil)
}

func afterHelloCmd(ver, cmd float64, data map[string]interface{}, userData *user.User,  next func(error)) {
 logger.Debug("This is executed after Hello command has been handled")
 next(nil)
}

func pushCmd(ver, cmd float64, data map[string]interface{}, userData *user.User, next func(error)) {
 // data is the parsed JSON data sent from the client
 logger.Debug("Data %#v SID:%s - UID:%s", data, userData.SID, userData.ID)
 // we send a push packet to the client that sent the data to this command
 userData.ServerPush(uint8(ver), uint16(cmd), data, true)
 // 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.
// dataMap is a map[string]interface{} type and will be encoded as a JSON to be sent to the client
// 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(dataMap, 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.
// dataMap is a map[string]interface{} type and will be encoded as a JSON to be sent to the client
// reliable is used for UDP server only and if this is set to true, the response becomes RUDP
userData.ServerRespond(cmdVer, cmdID, dataMap, reliable)