8. 通信エラーとボタンの連打に対応する
作ったショップで、購入ボタンを続けて押したり、通信を切ったりしてみましょう。これまで使ってきたプレイヤーで進めます。
処理中にもう一度押してみる
- コインを 20 枚以上用意します。足りない場合は冒険をクリアして集めます。
- 20 コインでスタミナを 10 回復 を押し、すぐにもう一度押してみます。
- 処理中はボタンが無効になり、次の購入を始められないことを確かめます。
コードでは、操作を始めるときに busy を true にし、finally で false に戻しています。ボタンの表示だけでなく、Studio の Run()、SDK の RunWrite() でも処理中の呼び出しを止めています。
購入が完了してボタンが有効になった後に押すと、それは新しい購入になります。
コインが足りないときの表示を確かめる
- 購入を繰り返し、コイン残高を 20 枚未満にします。
- もう一度購入ボタンを押し、コイン不足のメッセージが表示されることを確かめます。
- 失敗した購入でコインが減らず、スタミナも回復していないことを確認します。自然回復で増えた分は除いて比べてください。
- 森の探索を始め、冒険の操作は続けられることを確かめます。確認できたらクリアします。
コインやスタミナの不足は、理由を表示して次の操作を受け付けます。
同じ購入を再試行できるようにする
通信が切れたとき、サーバーでは購入が終わっていて、返事だけが届いていないことがあります。そのまま新しい購入を送ると、もう一度コインを使ってしまいます。
そこで、1回の購入に一つのキーを付けます。duplicationAvoider に同じキーを渡して同じ内容を送り直すと、GS2 は完了済みの購入を繰り返さず、その結果を返します。
Unity の再生を止め、使っているコースのファイルで、同名のファイルを置き換えてください。Inspector の参照はそのまま使います。
AdventureStudioView.cs をダウンロードします。
購入を行う Buy() は、次のようになります。purchaseId はクラスのフィールドです。
private string purchaseId;
private async Task Buy()
{
purchaseId ??= Guid.NewGuid().ToString();
var request = Gs2ClientHolder.Instance.Gs2.Exchange.Namespace("EnergyProduct")
.Me(Gs2GameSessionHolder.Instance.GameSession).Exchange();
var transaction = await request.ExchangeAsync(
"refill", 1, speculativeExecute: false, duplicationAvoider: purchaseId);
if (transaction != null) await transaction.WaitAsync(all: true);
purchaseId = null;
}AdventurePlay.cs をダウンロードします。AdventurePlayer.cs と AdventureLogin.cs はそのまま使います。
購入を行う BuyRefill() は、次のようになります。purchaseId はクラスのフィールドです。
private string purchaseId;
private async UniTask BuyRefill()
{
purchaseId ??= Guid.NewGuid().ToString();
var transaction = await player.Gs2.Exchange.Namespace("adventure-shop").Me(player.Session)
.Exchange().ExchangeAsync(
"refill", 1, speculativeExecute: false, duplicationAvoider: purchaseId);
awaitingResult = true;
if (transaction != null) await transaction.WaitAsync(all: true);
purchaseId = null;
}??= は、値がないときだけ代入する書き方です。通信に失敗しても purchaseId が残るので、再試行には同じキーを使います。購入が完了したら空に戻し、次の購入では新しいキーを作ります。コイン不足で購入できなかったときも、エラー処理で空に戻します。
通信エラー後のボタンは 同じ購入を再試行 に変わります。結果を受け取るまでは、別の冒険や新しい購入を始めず、この購入を送り直せるようにしています。
通信を切ってみる
- Unity を再生してログインします。コインを 20 枚以上用意し、スタミナを 10 以下にして、購入前の値を控えます。
- パソコンのネットワーク接続を切り、購入ボタンを押します。
- 通信エラーが表示され、ボタンが 同じ購入を再試行 に変わるまで待ちます。
- ネットワーク接続を戻し、Unity を再生したまま 同じ購入を再試行 を押します。
- コインが 20 減り、スタミナが 10 回復することを確かめます。自然回復で増えた分は除いて比べてください。完了すると、ボタンは通常の購入表示に戻ります。
次は、接続した状態で購入ボタンを押した直後に通信を切り、同じように試してみましょう。応答が先に届いて購入が完了した場合は、通常の購入ボタンに戻ります。再試行の表示になった場合だけ、接続を戻して送り直します。
このサンプルは、Unity の再生中にキーを保持します。Play を止めずに試してください。GS2 が重複回避の結果を保存する期間は1時間なので、この練習では通信を戻したらすぐに再試行します。
練習:状況に合うメッセージを考える
「処理中です」「コインが足りません」「通信を確認してください」など、今の状況が分かるメッセージに変えてみましょう。Studio は Run()、SDK は RunWrite() と WriteError() に表示文があります。