# Program 2, multiThreading report ###### tags: `operating system`, `courses` :::success ### mini-online-server - Server - [x] Socket - [x] Thread - Player - [x] set name - GameRoom - [x] create - [x] join - [x] chat - [x] leave & delete - [ ] start game - Game (not yet..) - [x] Rule design - [ ] ... ::: ## Environment - OS ```shell= ❯ uname -a Linux wasabineko-B550-AORUS-PRO-AC 5.8.0-50-generic #56~20.04.1-Ubuntu SMP Mon Apr 12 21:46:35 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux ``` - Language Python 3.8 - IDE PyCharm Community ### source code - [github](https://github.com/wasabi-neko/mini-online-server) ## Logic ### socket socket 是一種對於連續網路封包溝通的工具,可使用 TCP 或 UDP 協定來傳輸資料 ### Thread 主 thread 監聽目標 port 看有沒有新的連線,若有則建立一個新的 thread 負責服務此 socket 連線 ```sequence Client1 -> server: request for socket server -> thread_pool: create thread1 for Client1 thread_pool -> Client1: thread1 accept socket ``` ```graphviz digraph { rankdir=LR; subgraph outside { client_1 [label="Client 1"]; client_2 [label="Client 2"]; s_1 [label="socket service" shape="box"]; s_2 [label="socket service" shape="box"]; {rank=same; client_1, client_2} } subgraph cluster_server { label="server"; listen [label="listen port" shape="box"]; process [label="main loop" shape="Mrecord"]; t_1 [label="thread 1"]; t_2 [label="thread 2"]; } client_1->listen [label="request"] client_2->listen [label="request"] listen->process process->t_1->s_1 process->t_2->s_2 } ``` ### Chat Room Logic Client 有 `Disconnected`, `Lobby`, `Room` 三種狀態 不同狀態的指定集和目標對象不同 ```graphviz digraph { label="Client status" rankdir=LR; Disconnect -> Lobby -> Room [dir="both"] } ``` `Lobby console` 沒有實例(instance) 單純為 thread 內的資料操作 `RoomManager` 為 `singelton` 物件,負責管理所有的 `room`。 `Room` 實體,為 `shared memory`,可以被所有的 `thread` 請求,在修改資料時會使用 lock 以避免 race condition ```graphviz digraph { node[shape="record"] subgraph cluster_thread { label="thread" c1 [label="<f0> client 1 |<f1> console|<f2> room_ptr|<f3> renderer"] if1 [label="switch" shape="diamond"] lobby [label="<f0> lobby console |{method |{<f1> create room|<f2> join room} }"] } rm [label="{<f0>Room manager|<f1> room list}"] r [label="<f0> room console|{method |{<f2> leave|<f1> say}}"] c1:f1 -> if1 [label="(command, self)"] c1:f2:w if1 -> lobby:f0 [label="if status is lobby"] lobby:f1 -> rm [label="create room"] rm -> lobby:f2 [label="get room by name"] lobby:f2:e -> c1:f2 [label="assign"] if1 -> r:f0 [label="if status is room"] c2 [label="Client 2 | ...."] c3 [label="Client 3 | ...."] r:f1 -> c1:f3 [label="board cast"] r:f1 -> c2 [label="board cast"] r:f1 -> c3 [label="board cast"] r:f2 -> c1:f2 [label="delete"] } ``` ## References - https://ithelp.ithome.com.tw/articles/10205819 - https://www.geeksforgeeks.org/socket-programming-python/ - https://www.geeksforgeeks.org/multithreading-python-set-1/ - https://www.geeksforgeeks.org/socket-programming-multi-threading-python/ - [really good artical](https://realpython.com/python-sockets/) - [淺談IO](https://medium.com/@clu1022/%E6%B7%BA%E8%AB%87i-o-model-32da09c619e6)