Closed metalalive closed 9 months ago
- /game/{game-id}/join <-- Not sure whether this is good design option
- For later comer who attempts to join a game which hasn't been started yet
設計方針是只與GaaS大平台串接還是會有考慮其他遊戲登錄平台? 這是指之後有其他玩家也想要加入遊戲房間,所以一同遊玩人數會變更的情境嗎? 如果是GaaS大平台串接, 因為是等大平台那邊玩家都組好隊, 才會送過來,當送過來後, GaaS也沒辦法在新增玩家進來, 所以我認為先不考慮這個功能
/game/{game-id}/chat
不是很懂,看前面一條我以為是在討論REST endpoint?
可是下面解釋說是"player chatting with other players" 所以是在講socket.io
?
我不認為玩家聊天API需要在REST endpoint也建置對應的,徒增複雜度
socket.io的話 namespace 官網圖有點難懂
其實就是像這篇文章介紹的
Client可以建立很多socket連線到不同的namespace,每個namespace又可以分很多room
在我們遊戲這個case,
我認為很簡單的用原本預設的/
就好,
然後共同遊戲的玩家都在同一個game-id
的room內
There should be many more topics to subscribe for each player
是在講Kafka?我還沒開始看,暫時不了解設計上需要什麼
如果是在講socket.io的event namespace
目前我想到兩個設計方案
(1)
因為是傳送和game相關的可能是命名為game_state
或者直接叫game
之類的
通常event namespace
和上面剛剛提到的namespace
命名上最大區別就是最前頭會不會加上/
如果是與玩家聊天相關的內容,
傳送資料結構內可能會用Message_Type
來區分兩者。
(2)
另外一個設計方案就是
將玩家聊天相關內容獨立出來,event namespace
命名就chat
之類的名稱
這樣可以明確分隔傳送的是遊戲狀態更新(game
)還是聊天訊息(chat
)
加上之前討論我說
考慮只傳送差異更新而不是完整遊戲狀態
為了舉例方便,我用JSON示範 具體程式碼片段可能會像
# 已從Kafka接收到新的難度等級
new_difficulty_level = STANDARD
# 發布遊戲狀態更新到前端
sio.emit(
'game',
{'event': CHANGE_DIFFICULTY_STATE,
'difficulty': new_difficulty_level},
to=game_id
)
Hi, Ted, 我先回答部分問題
設計方針是只與GaaS大平台串接還是會有考慮其他遊戲登錄平台?
只考慮 GaaS 大平台
這是指之後有其他玩家也想要加入遊戲房間,所以一同遊玩人數會變更的情境嗎? 如果是GaaS大平台串接, 因為是等大平台那邊玩家都組好隊, 才會送過來,當送過來後, GaaS也沒辦法在新增玩家進來, 所以我認為先不考慮這個功能
是的, 目前的 GaaS 大平台 無法增加更多玩家到 已存在的遊戲房間 我以為這部分是由每個遊戲應用程式處理, 所以我最初的問題是 :
/game/{game-id}/join
, 讓一些稍後過來的玩家 能進入房間 ?
socket.io
server , 然後 subscribe event , with the namespace /game/{game-id}/join
?但ok , 這也不是關鍵功能,可以先不考慮
- /game/{game-id}/chat
不是很懂,看前面一條我以為是在討論REST endpoint? 可是下面解釋說是"player chatting with other players" 所以是在講socket.io?
這不是 REST endpoint
, 這是 event namespace
, 這是官方文件中的範例
https://localhost:8082/
連接到 socket.io
server/game/{game-id}/chat
, 接收同一遊戲房間 其他玩家的訊息/game/{game-id}/config/investigators
如果任何玩家更改了 investigator ,這個事件應該反映到同一房間的其他玩家/game/{game-id}/config/difficulty
, 如果任何玩家更改了 difficulty level ,這個事件應該反映到同一房間的其他玩家所以我最初的comment 是問你們對 namespaces, topics 的命名規則有何偏好 與 REST endpoint 無關,抱歉造成混淆
其實就是像這篇文章介紹的 Client可以建立很多socket連線到不同的namespace,每個namespace又可以分很多room
OK
/game
for 遊戲狀態更新/chat
for 聊天訊息/something/else
/game/{game-id}/chat
如果您希望聊天訊息僅在 特定房間的玩家可以看到/game/{game-id}/config/investigators
/game/{game-id}/state/card-draw
{game-id}
是代表遊戲 ID 的動態字串game/{game-id}
, there could be rooms such as chat
, config
, state
...etc
在我們遊戲這個case, 我認為很簡單的用原本預設的
/
就好, 然後共同遊戲的玩家都在同一個game-id的room內
Where to place the game ID ? should game ID be part of topic or namespace ? like /game/{game-id}
.
Or each room under the namespace /game
is identified by game ID ?
Hi, Ted , continue to reply rest of the questions
是在講Kafka?我還沒開始看,暫時不了解設計上需要什麼
please ignore the message , it is unrelated to Kafka ,
currently let's focus on socket.io
namespaces in the game app.
如果是在講socket.io的event namespace 目前我想到兩個設計方案 (1) ...... omitted ........ (2) 另外一個設計方案就是 將玩家聊天相關內容獨立出來,event namespace命名就chat之類的名稱 這樣可以明確分隔傳送的是遊戲狀態更新(game)還是聊天訊息(chat)
I prefer the 2nd design option, but I am not sure whether I can set up the namespace such like /game/{game-id}
in the backend app (where {game-id}
is a variable can be changed dynamically) , I will try the library python-socketio in my local development environment & reply later with my experiment result .
想問一下 State card draw 是想用來做甚麽的 是回合抽卡完成 誰的回合 還是別的
我在想把卡有關的的endpoints 可以group 到 /game/{gameId}/card 之下 所以想了解一下這條endpoint 的用意是甚麽
State card draw 是想用來做甚麽的 是回合抽卡完成 誰的回合 還是別的
抱歉,我只是舉個例子, 目前我還沒考慮實作細節 請忽略這個 card draw
Finally I got some time to work on the socket.io server, I will first start implementation which publish / subscribes message with the following topics -- 我目前正在做的 socket.io topics
/game/{game-id}/chat
/game/{game-id}/config/investigators
To everyone following / interested with this issue, here is the experiment result, feel free to ask question, I appreciate any feedback about the code and design, If I don't get any reply by the end of Thursday afternoon (17:30:00 , 7th. Dec. 2023) , I will continue working on the real-time chat implementation and then quickly create a PR.
[1]
The comment in this python-socketio
issue describes that socket.io
client with http
requires aiohttp
, otherwise there will be timeout exception on the client side. In this game backend app , socket.io
client is used ONLY for testing purpose, it is suggested to install aiohttp
in test dependency of poetry config file.
[2]
the namespace
in python-socketio
seems more like a constant than a variable, it might NOT be good practice to generate namespace dynamically at runtime. Quote my previous comment :
I prefer the 2nd design option, but I am not sure whether I can set up the namespace such like
/game/{game-id}
in the backend app (where{game-id}
is a variable) , I will try the librarypython-socketio
in my local development environment & reply later with my experiment result .
After coding with python-socketio
library, I decided to give up doing that , instead I set {game-id}
to room
with each event and namespace .
[3] For testing
AsyncClient
, which monitors events by registering event-handling callbacks to the method on(...)
, however the handler callback does not seem to provide any argument that represents which client is receiving which message , which is NOT friendly to tests.AsyncSimpleClient
in test case, it provides the method receive(...)
for getting events from socket.io
server, this is good for understanding which client is receiving which message.[4]
I pushed my commits to the branch experiment/backend/socketio
(it is only for experiment purpose) , this comment will be no longer edited .
To @wingtkw :
I have done the socket.io
experiment (see the result above)
I am considering to add another API doc at doc/api
for the socket.io
real-time communication,
this document requires both of frontend and backend contributors working together,
can you check the test case in the branch /experiment/backend/socketio
to see whether is it OK for chat event ?
currently there are fields like client
,gameID
, and msg
in the chat event, please take a look , thanks.
To anyone interested with the work, you are also welcome to discuss with us , (I don't tag anyone else here, feel free to get involved), thanks
the list is what I will do :
socket.io
servernickname
to the data of the chat event (what other fields required by frontend app ?)remove first forward slash character /
from each event name, e.g. /chat
renamed to chat
create PR, merge to main branch --- (done in 11th Dec 2023)
socket.io
server needs to know which game rooms are created, which players are currently in which roomsocket.io
server knows about it ? : socket.io
server maintains some kind of table map, and the table map records events emitted from REST server on creating game <-- (preferred, more de-coupled)socket.io
server directly read from game repository through the abstract interface. Remind that :
- GaaS Lobby platform creates a new game , by sending request to the REST endpoint
/games
, withPOST
method and list of player IDs- currently we (this game dev team) don't consider to let more players (or late comers) join an existing game room
create PR, merge to main branch --- (done in 26th Jan 2024)
socket.io
server, the socket.io sevrer forwards the events to the playerscreate PR, merge to main branch --- (done in 1st Feb 2024)
FlatBuffers
or ProtoBuf
(see previous discussion)create PR, merge to main branch --- (done in 7th Feb 2024)
通常
event namespace
和上面剛剛提到的namespace
命名上最大區別就是最前頭會不會加上/
我注意到實驗分支 experiment/backend/socketio 實作中
event namespace
命名開頭都加上/
, 例如 /chat
, /init
等
好奇這樣取名原因是?
一些相關討論: Custom event naming convention Is there any name convention for response event in socketIO?
補充說明:
namespace
會當作URL的一部分,所以開頭第一個字元固定為/
如果預設連接的URL為http://xxx.example.com/
用預設的namespace="/"
當為socket.io
時,URL實際連結會像http://xxx.example.com/socket.io/?EIO=4&transport=websocket
當namespace="/game"
實際上代表連接的URL為http://xxx.example.com/game
當為socket.io
時,URL實際連結會像http://xxx.example.com/game/socket.io/?EIO=4&transport=websocket
至於event namespace
是socket.io內部通訊event
實作,跟連接的URL無關
I am considering to add another API doc at doc/api for the socket.io real-time communication,
socket.io 文件通常用 AsyncAPI 撰寫, 但我不確定同樣放在doc/api
這樣能不能相容, 或者放在doc/socketio
?
Pt1
Pt2
Hi , Ted
event namespace
命名開頭都加上/
, 例如/chat
,/init
等 好奇這樣取名原因是?
The naming convention of socket.io
event really depends on development team (at least the name has to reflect the corresponding operation done by server or each client), it can be changed.
And yes, there is no reason to add extra slash symbol /
at the beginning of event name, this can also be removed,
current events can be renamed to chat
, init
, deinit
socket.io 文件通常用 AsyncAPI 撰寫, 但我不確定同樣放在doc/api這樣能不能相容, 或者放在
doc/socketio
?
thanks, good to know about AsyncAPI
and event-driven architecture API document
It is also OK to place it in different path such as doc/socketio
,
Let us focus on the 2nd portion of the TODO list in this GitHub Issue , discussion related to the design / implementation are appreciated.
RtcRoomRepository
or what else.[update 15th Dec 2023] I am fighting against tricky tech issues in other projects, will start working on this once I have time.
[update 11th Jan 2024] I'll also check whether I can get this done without setting up Kafka
[update 23th Jan 2024]
http
server can act as socketio
client emitting events to socketio
server without Kafka
Let me review it on 15 Got AL on that day
I am working on the 3rd portion of the TODO list in this GitHub Issue , discussion related to the design / implementation are appreciated.
I will work on the 4th (final) portion of the TODO list in this GitHub Issue.
I'll try FlatBuffers
first with socket.io
server and see how it goes
@wingtkw , @KalpasWang , @liamlin1102 Appreciate discussion / your feedback related to the design / implementation.
Currently close this Issue, any code / design contributor can reopen it whenever there is new event to add in the real-time communication.
c.c. @wingtkw , @KalpasWang
@metalalive it seems everyone disappear except us, what happened? 🤔
API endpoint to
socket.io
serverlocalhost:8082
, path/
,GET method, no request bodyInteraction with
socket.io
serverClient (Player)
Possible events namespace to emit (or topics to publish)
/game/{game-id}/join
<-- Not sure whether this is good design optionplayer-id = abc999xyz
/game/{game-id}/chat
player-id = abg007xyz
,chat-message = Hello World
Possible events namespace to receive (topics to subscribe)
/game/{game-id}/config/difficulty
level = standard
,/game/{game-id}/config/investigators
player-id = SamuraiBuck
,investigator = magician
There should be many more topics to subscribe for each player
HTTP RESTful server
Possible events namespace to emit (or topics to publish)
/game/{game-id}/config/difficulty
/game/{game-id}/config/investigators
Possible events namespace to receive (topics to subscribe)
Question
/game/{game-id}/join
, <-- is this good design option ?/game/{game-id}/join
? to let the HTTP RESTful server know one more person would like to join , then re-useGame.add_player()
in backend code.TODO
python-socketio
and Kafka)Reference
See previous discussion #29
@wingtkw @teds-lin , plz take a look at this, feedback or suggestion are welcome , thanks.