Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
cocone TECH TALK Vol.6 - リアルタイム対戦xバックエンドアーキテクチャ
Search
cocone
May 08, 2023
Technology
700
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
cocone TECH TALK Vol.6 - リアルタイム対戦xバックエンドアーキテクチャ
cocone
May 08, 2023
More Decks by cocone
See All by cocone
Cocone_Research_Center_2025.pdf
cocone
0
320
20240301_cocone_EMゆるミートアップvol6_LT資料
cocone
0
940
2024_cocone-wellbeing
cocone
0
5.1k
2023夏季合同企業説明会ココネ
cocone
0
410
cocone TECH TALK Vol.6 - ココネグループのブロックチェーン MOOI Network とのバックエンド連携
cocone
0
630
cocone TECH TALK Vol.6 - Kotlin バックエンドアーキテクチャ of アバターサービス
cocone
0
630
cocone corporation(JPN)/Handbook2022
cocone
1
31k
cocone Tech Talk vol.5 - Unity Dotsを使ってみた
cocone
0
2.5k
cocone corporation(JPN)/Letter to Planner
cocone
0
590
Other Decks in Technology
See All in Technology
AWS Security Hub CSPMの成功・失敗体験
cmusudakeisuke
0
230
Oracle AI Database@Azure:サービス概要のご紹介
oracle4engineer
PRO
6
2k
新しいUbuntu/GNOMEが使いたいからXからWaylandへ移行頑張ってるの巻 2026-06-20
nobutomurata
0
150
就職⽀援サービスにおけるキャリアアドバイザーのシフトスケジューリング
recruitengineers
PRO
1
150
【NRUG vol.18】KubernetesにおけるNew Relicデータ取得量削減の考え方
nrug_member
0
160
2026年6月23日 Syncable Tech + Start Python Club にて
hamukazu
0
140
AIネイティブな開発のサプライチェーンリスク対策 〜激動の開発現場でリスクに立ち向かう〜【ZennFes】
cscengineer
PRO
2
140
【2026年版】 ベクトル検索とEmbedding最前線
mocobeta
14
3.9k
フィジカル版Github Onshapeの紹介
shiba_8ro
0
290
Claude Codeをどのように キャッチアップしているか
oikon48
13
8.5k
日本 Fintech 未来予測レポート 2027〜2028年(オリジナル版)
8maki
0
2.3k
AIのReact習熟度を測る
uhyo
2
650
Featured
See All Featured
Docker and Python
trallard
47
3.9k
WENDY [Excerpt]
tessaabrams
11
38k
Building Applications with DynamoDB
mza
96
7.1k
Color Theory Basics | Prateek | Gurzu
gurzu
0
370
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
1.7k
Agile that works and the tools we love
rasmusluckow
331
21k
sira's awesome portfolio website redesign presentation
elsirapls
0
280
The Curious Case for Waylosing
cassininazir
1
390
Skip the Path - Find Your Career Trail
mkilby
1
150
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
200
Side Projects
sachag
455
43k
Transcript
リアルタイム対戦 × バックエンドアーキテクチャ RYO TOMARU
自己紹介 職歴 ゲーム系企業でクライアント /サーバーを主軸に しつつ、配信サービスのフロントエンド実装など も経験。 趣味 個人ゲーム開発、ドット絵、最近引退気味です が光の戦士。最近はGolangとFlutterが好き。 戸丸
良 / RYO TOMARU
本日の内容 • どのような技術を用いて「リアルタイム対戦」を実現したか • 通信フローについてのご紹介 • 苦労したポイント ※詳細なインフラ構成については今回の範囲外となります ...。
目次 1. リアルタイム通信をどの技術で実現するか 2. 今回採用した技術 3. 苦労したポイント 4. まとめ
リアルタイム通信をど の技術で実現するか
多彩な選択肢 最近では、ゲームエンジン側でもサポートが進むなど、開発がしやすい環境となってきてい る。 • 純粋なSocketを用いて構築する • Unity+MLAPI/Mirror/DOTSNET … • Unity
+ Photon/モノビットエンジン/MagicOnion • gRPC Bidirectional Streaming RPC • WebSocketやDatagram … etc …
選択肢が多い上に、一つ一つが難しい
多彩な選択肢 「リアルタイム通信対戦がしたい」だけであれば、どの手段でも実現は可能。 ここに「サービス・ゲームデザインとしてはどうか 」「運用保守の面でどうか」「UXとしてどう か」など、様々な要素を加えて選択していく必要がある。 (難しい・・・) 今回は担当プロダクトにおいて、どのような選択をしたのか、苦労話と合わせてご紹介しま す。
今回採用した技術
gRPCを利用 • 他の機能(API)はgRPCで実装していたため、同一の運用で対応したかった • Unary RPC ◦ Request/Response ◦ 一般的なAPI
• Client Streaming RPC ◦ Clientから任意にデータ送信が可能 ◦ ファイルアプロードなど • Server Streaming RPC ◦ Serverから任意にデータ送信可能 ◦ 通知など • Bidirectional Streaming RPC ◦ 双方向通信 ◦ 相互に任意のタイミングでデータ送信が可能
初期に採用したのは・・・ • 初期(モック)時点では、ゲームデザインが完全に FIXしていなかった • 単純に双方向を選択しておけば大抵なんとかなるよね、から選択 • 慣れていた gRPC Bidirectional
Streaming RPC
gRPC Bidirectional Streaming • 俗に言う双方向通信 • クライアント、サーバー相互に任意のタイミングでデータ送信が行える • oneofを使用し、一つのstreamで複数のコマンドを定義 message
Notify { // どれか1つの情報がくるので、 switchなどで処理を振り分ける oneof event { ChatInfo chat_info = 1; Actor join_actor = 2; … } } service StreamingService { rpc StartNotify(...) returns (stream Notify) {} … }
順調に実装は進んでいったが・・・
実装自体は進んだが、次第に様々な問題が発生 複雑化するコード Client/Server間のやり取りの増加 操作に対して必ず結果が必要 テストの複雑化 増えるoneof 開発コスト増加 send/recvそれぞれのgoroutineを 管理する必要 このメソッドってクライアントに何か投
げるんだっけ・・・? 増え続けるoneof 増え続けるoneof 増え続けるoneof
pickup 増え続けるoneof • Request/ResponseをC/Sのmessageへ追加する • 関係性が非常に難解 message ClientNotify { oneof
event { Say say = 1; Foo foo = 2; Bar bar = 3; Echo echo = 4; … } message Say {...} … } message ServerNotify { oneof event { SayResult say_result = 1; FooResult foo_result = 2; BarResult bar_result = 3; EchoResult echo_result = 4; … } message SayResult {...} … }
まだ間に合う・・・はず! (そもそもゲームデザイン的にあっていないのでは? )
最終的な着地点 • gRPC + Unary RPC + Server Streaming RPC
• 各種操作については、Unary RPC(Request/Response)へ変更 • 自身の操作などはServer Streaming RPCを利用して通知 • より詳細な情報が必要であれば Unary RPCで取得 gRPC + Unary RPC + Server Streaming RPC 意外とすんなりいけるはず
最終的な着地点 • gRPC + Unary RPC + Server Streaming RPC
• 各種操作については、Unary RPC(Request/Response)へ変更 • 自身の操作などはServer Streaming RPCを利用して通知 • より詳細な情報が必要であれば Unary RPCで取得 gRPC + Unary RPC + Server Streaming RPC 全部書き直した
gRPC + Unary RPC + Server Streaming RPC
Redis PubSubを利用
結果としてどうなったか • 基本的にUnary RPCを利用するため、フローがシンプルになった ◦ いつも通りの実装、テスト手法が通用した • Request/ReponseがIDLにて明示的に定義されるため、読みやすい ◦ この操作きたら何を返すんだっけ・・・が無くなった
• Unaryは操作、Streamingはサーバーからの通知と役割を切り分けられた ◦ CRUDとNotifyを切り離せたので、可読性が上がった
苦労したポイント
苦労したポイント 再接続時の復帰処理 復帰時の進行状況に応じて状態を再現する必要があった。 また切断中は自動行動を行うため、タイミングによっては進行不能になるなど、 リリース直前まで頭を悩ませられた。 細かいエッジケース対応 〜の時に〜をするとバグる、という様な話が初期は特に多かった。 最終的にはBOTを作成し、自動的にバトルを繰り返す仕組みでカバーした。 ローンチ後、大きな問題は起きていないので、良い結果が出せた。 参考:
https://qiita.com/maruc/items/2393647be5caa32623e3
苦労したポイント PubSubに悩まされた go-redisを使用していたが、コネクション数が多大になったり、 ConnectionPoolとPubSubの接続状態連携が行われていないなど ...。 最終的にはある程度自前でコントロールを行った。 負荷対策 システム上、最新のデータを取得するケースが多く、 Primaryアクセスが頻発。 キャッシュアサイドパターンを用いることで、負荷軽減を行った。
(整合性を担保する必要があるので、可能であれば避けたい所ではあった)
pickup go-redis pubsub • 1購読=1コネクションが貼られる • アクティブが1万人いたら1万コネクション ◦ パフォーマンスが著しく低下 ◦
ElasctiCacheの上限にもかかる • 最終的にAPでコネクションを自前プールするよう実装 • 一つのコネクションで複数サブスクライブできるように変更 • 内部的に各Sessionのgo:channelへpush ◦ ch <- event
まとめ
まとめ • 当たり前ですが「ゲームデザインにあった」技術選定、設計が重要。 • 表面上動くものはすぐに作れる時代ではあるが、その先が深い。 ◦ このタイミングで切断されたら・・・ ◦ 地下鉄で瞬断したら・・・ ◦
バイナリが改造されたら・・・ etc • 「どのようにテストを行うか」も初期段階で考えておくと良い。 • 開発中はクライアント担当とずっと「うーん・・・」と唸ることになる。 • ・・・とはいえ、開発自体は楽しい!
ご静聴ありがとうございました