リアルタイムメッセージング機能

Sora Unity SDK のリアルタイムメッセージング機能について説明します。

この機能を利用することで、チャネル参加者に対してリアルタイムにメッセージを送受信することができます。

リアルタイムメッセージング機能について

リアルタイムメッセージング機能を利用するためには、data_channel_signaling を有効にする必要があります。

細かな設定方法については Sora ドキュメント を参照してください。

Sora Unity SDK の実装内容

Sora Unity SDK では、リアルタイムメッセージング機能を利用するための実装を以下のように提供しています。

// データチャネルの設定を保持するクラス
public class DataChannel
{
    // 必須設定項目
    public string Label = ""; // チャネルのラベル
    public Direction Direction = Sora.Direction.Sendrecv; // チャネルの送受信方向

    // 以下はオプション設定
    public bool? Ordered; // メッセージの順序保証
    public int? MaxPacketLifeTime; // パケットの最大寿命 (ms 単位)
    public int? MaxRetransmits; // 最大再送回数
    public string? Protocol; // チャネルで使用するプロトコル名
    public bool? Compress; // データの圧縮を有効化するか
    public List<string>? Header; // ヘッダー情報
}

// データチャネルの設定を保持するリスト
public List<DataChannel> DataChannels = new List<DataChannel>();

// config.DataChannels の設定を内部のデータチャネル構造に変換して追加
foreach (var m in config.DataChannels)
{
    // データチャネルの方向を文字列形式に変換
    var direction =
        m.Direction == Direction.Sendonly ? "sendonly" :
        m.Direction == Direction.Recvonly ? "recvonly" : "sendrecv";

    // 内部のデータチャネル設定オブジェクトを生成
    var c = new SoraConf.Internal.DataChannel()
    {
        label = m.Label, // ラベルを設定
        direction = direction, // 送受信方向を設定
    };

    // オプション項目を設定 (null でない場合のみ)
    if (m.Ordered != null)
    {
        c.SetOrdered(m.Ordered.Value); // 順序保証を設定
    }
    if (m.MaxPacketLifeTime != null)
    {
        c.SetMaxPacketLifeTime(m.MaxPacketLifeTime.Value); // 最大寿命を設定
    }
    if (m.MaxRetransmits != null)
    {
        c.SetMaxRetransmits(m.MaxRetransmits.Value); // 最大再送回数を設定
    }
    if (m.Protocol != null)
    {
        c.SetProtocol(m.Protocol); // プロトコル名を設定
    }
    if (m.Compress != null)
    {
        c.SetCompress(m.Compress.Value); // 圧縮の有効/無効を設定
    }
    if (m.Header != null)
    {
        // ヘッダー情報を設定 (リストを内部形式に変換)
        c.SetHeader(new SoraConf.Internal.DataChannel.Header { content = m.Header });
    }

    // 内部データチャネルリストに追加
    cc.data_channels.Add(c);
}

// メッセージの受信
public Action<string, byte[]> OnMessage
{
    set
    {
        if (onMessageHandle.IsAllocated)
        {
            onMessageHandle.Free();
        }

        onMessageHandle = GCHandle.Alloc(value);
        sora_set_on_message(p, MessageCallback, GCHandle.ToIntPtr(onMessageHandle));
    }
}

利用方法

リアルタイムメッセージング機能を利用するためには、以下の条件を満たす必要があります。

  • Sora の設定でリアルタイムメッセージング機能が利用可能になっていること

  • data_channel_signaling が有効になっていること

  • data_channels の設定が行われていること

  • # から始まる label が設定されていること

  • direction が設定されていること

以下に Sora Unity SDK Samples でのリアルタイムメッセージング機能の利用方法を示します。

設定は Inspector で実施することを想定したものです。

また、メッセージの送信はゲーム画面上の UI から行うことを想定しています。

ご利用になる用途に合わせて適宜変更してください。

// データチャネルの設定をするクラス
[System.Serializable]
public class DataChannel
{
    // 必須設定項目
    public string label = ""; // データチャネルのラベル
    public Sora.Direction direction = Sora.Direction.Sendrecv; // チャネルの送受信方向

    // 以下は各オプション項目を有効にするためのフラグと設定値
    public bool enableOrdered; // 順序保証を有効化するか
    public bool ordered; // メッセージの順序保証設定
    public bool enableMaxPacketLifeTime; // パケット寿命設定を有効化するか
    public int maxPacketLifeTime; // パケットの最大寿命
    public bool enableMaxRetransmits; // 最大再送回数設定を有効化するか
    public int maxRetransmits; // 最大再送回数
    public bool enableProtocol; // プロトコル設定を有効化するか
    public string protocol; // 使用するプロトコル名
    public bool enableCompress; // 圧縮設定を有効化するか
    public bool compress; // 圧縮の有効/無効設定
    public bool enableHeader; // ヘッダー設定を有効化するか
    public string[] header; // ヘッダー情報 (文字列の配列)
}
[Header("DataChannel メッセージングの設定")]
public DataChannel[] dataChannels;
string[] fixedDataChannelLabels;

Sora に接続する際に設定を行う部分の例を以下に示します。

// Sora インスタンスの宣言
Sora sora;
// Sora.Config インスタンスの生成
var config = new Sora.Config();

// dataChannels が設定されている場合、処理を開始
if (dataChannels != null)
{
    foreach (var m in dataChannels)
    {
        // 新しい Sora.DataChannel インスタンスを生成
        var c = new Sora.DataChannel();
        c.Label = m.label; // ラベルを設定
        c.Direction = m.direction; // 送受信方向を設定

        // 各オプション項目の設定 (有効フラグを確認)
        if (m.enableOrdered)
        {
            c.Ordered = m.ordered; // 順序保証を設定
        }
        if (m.enableMaxPacketLifeTime)
        {
            c.MaxPacketLifeTime = m.maxPacketLifeTime; // 最大寿命を設定
        }
        if (m.enableMaxRetransmits)
        {
            c.MaxRetransmits = m.maxRetransmits; // 最大再送回数を設定
        }
        if (m.enableProtocol)
        {
            c.Protocol = m.protocol; // プロトコル名を設定
        }
        if (m.enableCompress)
        {
            c.Compress = m.compress; // 圧縮設定を有効/無効化
        }
        if (m.enableHeader)
        {
            // ヘッダー情報を文字列配列からリストに変換して設定
            c.Header = m.header.ToList();
        }

        // 設定済みのデータチャネルを config に追加
        config.DataChannels.Add(c);
    }

    // 設定したデータチャネルのラベルを配列に抽出
    fixedDataChannelLabels = config.DataChannels.Select(x => x.Label).ToArray();
}

メッセージの送信は以下のように行います。

// Sora インスタンスの宣言
Sora sora;

public void OnClickSend()
{
    if (fixedDataChannelLabels == null || sora == null)
    {
        return;
    }
    // DataChannel メッセージを使って全てのラベルに適当なデータを送る
    // ここでは "aaa" という文字列を送信している
    foreach (var label in fixedDataChannelLabels)
    {
        string message = "aaa";
        sora.SendMessage(label, System.Text.Encoding.UTF8.GetBytes(message));
    }
}

メッセージの受信は以下のように行います。

// Sora インスタンスの宣言
Sora sora;

sora.OnMessage = (label, data) =>
{
    // 受信したメッセージのラベルとデータをログ出力
    // dataはバイト配列として受信されるため、UTF8文字列に変換して表示
    Debug.LogFormat("OnMessage: label={0} data={1}", label, System.Text.Encoding.UTF8.GetString(data));
};
© Copyright 2024, Shiguredo Inc. Created using Sphinx 8.1.3