這星期練習了有關multy-thread跟socket通訊上的程式邏輯,把一些該注意或是新學習到的東西在這邊留一個筆記。
一般的遊戲在畫面上同時都有很多部分"看起來"同時在運作。例如打磚塊,玩家在控制那根棍子移動的同時,上面的球也同時在反彈跟移動。以前認為這樣的架構,應該同時有兩個不同的thread在分別控管棍子與球,剩下的就是管理好同步化避免兩個thread互相衝突。但在讀了一些其他高手所撰寫的遊戲程式後,才知道多數使用的方式應該是以一個主工作清單,集中管理下一個時間點該完成的工作事項,一一完成後運算畫面,最後再完成render的動作。
而JAVA的Socket,使用起來其實就像是一條電話線,先由Server端等電話,當某處的Client撥電話到Server端後,兩邊的線路就正式接通,彼此之間就能互相傳遞訊號。在java中,主要以Stream的方式傳輸訊號,當有一邊以Stream傳出資料後,資料會傳輸至接收端的buffer中,在接收端通常以while迴圈等待,將資料從buffer中抓出,當buffer為空時,getInputstream會以類似wait的方式等待,而不需要給一個while迴圈還加sleep(原本我就寫錯成這樣)。
java的Stream也是一種很方便的接口,只要能找到對的function將想傳輸的東西(文字、聲音、圖片)轉為Stream,就能配合Socket傳送或接收。
因此,上星期的練習目標就是,"傳送Object的多人連線Server端與Client端"。
最後寫出來的成果,最主要練習並實踐了一個可以多人連線的Server(與其Client端),以multi-thread進行資料的傳送、接收與同步。由於傳輸的單位是"Object",因此只要是能夠序列化的物件都能直接被傳送(應用範例中實踐字串與圖片的傳輸)。並將幾個可能會需要另外執行程式判斷的部分以interface的方式拉出另外建立,方便此工具未來配合各種程式開發需要(例如新客戶端連線時執行哪些事情?收到Object時執行哪些事情?)。
流程上,Server端開啟後,先建立一個空的工作清單,之後開始一個thread,處理Server的等待動作,從這邊開始,一旦有新的Client端連線至Server端(且Server端接受Client的開關設為開),則Server端將Client端的Socket加入清單中(加入清單的動作需要synchronized),開始一個專門處理該Client(傳送與接受)的thread,然後重新回到等待Client的狀態。
當一個處理Client的thread被建立時,便開始等待來自該Client的資料,一旦接收區buffer有資料進入,就將該資料填入Server端的工作清單中(這邊也需要synchronized),直到與Client端之間的連接產生Exception時,該thread通知Server,斷開連接,從Client清單中去除,完成使命自動消滅。
最後,Server端另外有準備一個執行工作的thread,當工作清單中有任何物件時,從工作清單中取出該物件(一樣還是synchronized),並且依照開發者給予的funtion執行,並將結果Boardcast給所有的Client(包含自己)。
開發者使用這個架構時,只需要考慮在開放出來的幾個時間點(接收到新Client端、或接收到來自Server的Boardcast資料等)所需要執行的程式,便可以方便運用這個程式.....至少對目前的我來說還滿好操作的~_~
另外完成一個使用上述架構的應用練習,一個簡單UI的多人聊天室,其實建立連線後傳送的就是一些字串與圖片,只是實踐了事件的interface,讓程式收到字串物件時將內容顯示於螢幕上的文字區塊中,收到圖片物件時開啟新視窗展示,詳細的原始碼與可執行jar檔在下面連結中:
Dropbox分享
最後由衷誠懇地希望,.........哪天我回來翻這篇文章時我還能找到我想要的答案lol
沒有留言 :
張貼留言