//tips
//VIVOX構造理解
プレイヤーのAccountIdが作られた後にvivoxのサインインのためにILoginSession.BeginLogin methodが呼ばれる。
After the AccountId is created, call the ILoginSession.BeginLogin method to sign in to Vivox.
BeginLogin methodは特定アカウントとしてサインインするためのゲームインスタンスを認識するトークンへのアクセス権を持つ。
Every BeginLogin method call must have an access token that authorizes that game instance to sign in as the specified account.
The EndLogin method must be called within a try block in case an error occurs.
アカウント名はDisplayName within the AccountId section of the Participant results from IChannelSessionとAccountId sectionの参加によって生じるIChannelSessionの結果に含まれるもののよう。
The game sets a display name for the account by using UTF-8 encoding. This name is visible to all users in the channel; they receive it as DisplayName within the AccountId section of the Participant results from IChannelSession.Participants.AfterKeyAdded, IChannelSession.Participants.BeforeKeyRemoved, and IChannelSession.Participants.AfterValueUpdated.
下記形がログインを行う上での各アカウントの処理
using UnityEngine;
using VivoxUnity;
class LogInExample : MonoBehaviour
{
. . .
void LoginUser()
{
// For this example, _serverUri, _tokenDomain, _tokenIssuer, _tokenKey are members with values from the Developer Portal and client is initialized.
var accountId = new AccountId(_tokenIssuer, "username-0001", _tokenDomain);
var _loginSession = client.GetLoginSession(accountId);
_loginSession.BeginLogin(_serverUri, _loginSession.GetLoginToken(_tokenKey,_tokenExpiration), ar =>
{
try
{
_loginSession.EndLogin(ar);
}
catch (Exception e)
{
// Handle error
return;
}
// At this point, login is successful and other operations can be performed.
. . .
});
}
}
. . .
}
また、ILoginSession eventsはさまざまなものがあり、それに対してeventとして処理していくことになる。
その中で最も重要なものがILoginSession.PropertyChanged,でセッションが接続状態を変化させたときに生じるものである。
You can subscribe to various ILoginSession events by using a standard C# EventHandler delegate style. The most important of these is ILoginSession.PropertyChanged, which occurs when the session changes connection state.
セッションの接続状態というのはLoginState.LoggedOutなどの状態のことを指す。
下記のようにILoginSessionとLoginStateのセッションの状態は管理されている。
using UnityEngine;
using VivoxUnity;
class LoginPropChangeExample : MonoBehaviour
{
. . .
_loginSession.PropertyChanged += onLoginSessionPropertyChanged;
. . .
private void onLoginSessionPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
if ("State" == propertyChangedEventArgs.PropertyName)
{
switch ((sender as ILoginSession).State)
{
case LoginState.LoggingIn:
// Operations as needed
break;
case LoginState.LoggedIn:
// Operations as needed
break;
case LoginState.LoggedOut:
// Operations as needed
break;
default:
break;
}
}
}
}
イベントを使用する際に、イベント処理は「出版/購読型」のパターン (Publish/Subscribe pattern) を実装するものなので、 Publisher が 1 に対して Subscriber は多数となるのが基本。そのため、イベントハンドラを設定する箇所は = ではなく、 イベントハンドラの追加の意味の += とするのだが、今回の場合PublisherとSubscriberは誰に該当するのだろうか。
_loginSession.PropertyChangedという発生イベントに対して、onLoginSessionPropertyChangedという実行内容を入れることになるが、onLoginSessionPropertyChangedの内容はcaseに対して一つになっているため=ではダメなのだろうか。
色々探ってみた結果、イベント発生(例えば、クリックなど)にて実行する処理内容を+=にて追加していくことになり、音を出す、色を変えるなど複数の処理を行う際には複数の処理内容を追加する必要がある。onclickの中身にいくつも実行内容を登録できることを思い出せばわかりやすい。
なので、ここでは_loginSession.PropertyChangedというイベントに対して他の処理内容を追加する可能性があるので、+=で問題ない。
下記の例が理解の助けになったので参考にあげる。
https://yutori-techblog.com/cs-event-cannotremove
上記理解をもとに早速コードを確認した。今回はログイン部分に絞ったコードとなっており、vivoxvoicemanagerも使用していない。こちらで単純なログインをすることができた。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VivoxUnity;
using System.ComponentModel;
using System;
public class LoginCredentials : MonoBehaviour
{
VivoxUnity.Client client;
private Uri server = new Uri("https://mt1s.www.vivox.com/api2");
private string issuer = "30-vo35-dev";
private string domain = "mt1s.vivox.com";
private string tokenKey = "b358";
private TimeSpan timeSpan = TimeSpan.FromSeconds(90);//new TimeSpan(90);//TimeSpan.FromSeconds(90);
//private AsyncCallback loginCallback;
private ILoginSession loginSession;
private void Awake()
{
client = new Client();
client.Uninitialize();
client.Initialize();
DontDestroyOnLoad(this);
}
private void OnApplicationQuit()
{
client.Uninitialize();
}
void Start()
{
//loginCallback = new AsyncCallback(Login_Result);
}
public void Bind_Login_Callback_Listeners(bool bind,ILoginSession loginSesh)
{
if (bind == true)
{
loginSesh.PropertyChanged += Login_Status;
}
else
{
loginSesh.PropertyChanged -= Login_Status;
}
}
public void LoginUser()
{
Login("TestName");
}
public void Login(string userName)
{
AccountId accountId = new AccountId(issuer, userName, domain);
loginSession = client.GetLoginSession(accountId);
Bind_Login_Callback_Listeners(true, loginSession);
loginSession.BeginLogin(server, loginSession.GetLoginToken(tokenKey, timeSpan), ar =>
{//loginCallback,Login_Resultを作成すると下記が不要になる。
try
{
loginSession.EndLogin(ar);//ログインが終わったらログイン完了のresult非同期
}catch(Exception e)
{
Bind_Login_Callback_Listeners(false, loginSession);
Debug.Log(e.Message);
}
});
}
public void Logout()
{
loginSession.Logout();
Bind_Login_Callback_Listeners(false, loginSession);
}
public void Login_Status(object sender,PropertyChangedEventArgs loginArgs)
{
var source = (ILoginSession)sender;
switch (source.State)
{
case LoginState.LoggingIn:
Debug.Log("Logging In");
break;
case LoginState.LoggedIn:
Debug.Log($"Logged In");
break;
}
}
}
下記を参考にしている。
こちらの関連動画を見ながらvivoxの細部を理解していくことにする。