iT邦幫忙

0

有關socket問題

您們好:

不好意思,最近在研究使用c#寫多人連線遊戲,但出現一個問題><

假設現在玩家A上線,會丟訊息給server,進而撈資料庫,server再將玩家A的基本資料傳到client,在client中會用Label顯示玩家的暱稱及等級等個人資料,但是當玩家B上線之後會覆蓋掉在Label上玩家A的資料(即兩個client端畫面的資料都變成玩家B的),當玩家C上線後,三個client端畫面的資料都變成玩家C的,Label上會一直這樣被覆蓋掉....
在label顯示上,會有跨執行緒問題所以用委派的方式撰寫,程式碼如下

private delegate void myUICallBack(string myStr, Control ctl);//步驟 1: 定義委派型別.
private void myUI(string myStr, Control ctl)
{
if (this.InvokeRequired)
{
myUICallBack myUpdate = new myUICallBack(myUI);
this.Invoke(myUpdate, myStr, ctl);
}
else
{
ctl.Text = myStr;
}
}

請問各位高手,要如何在每一個client端只單純顯示自己的資料而不被後來上線的玩家覆蓋掉呢?

請問是要用每位玩家的執行緒來對特定對象傳值嗎?還是有更好的方法呢?

不好意思,才疏學淺,麻煩各位高手解惑,實在感恩。

12
wiseguy
iT邦超人 1 級 ‧ 2012-02-12 17:23:28
最佳解答

錯誤一
如果 user 丟進資料庫的資料,會被其它 user 覆蓋,顯然這表格設計有問題,沒有分別各人資料的欄位。

錯誤二
如果 user 的 client 會把別的 user 的資料抓下來當自己資料秀,client 沒有辨別是否為自己資料的能力。

解法:每個 client 應該有唯一的識別碼,做為識別自己與資料庫關連的 key 值。

slime iT邦大師 1 級 ‧ 2012-02-12 18:27:44 檢舉

應該有一個"現有 Session (概念)表"來處理:

當玩家 A 透過電腦 甲 登入,若 Session 表內無相關資料,系統允許登入,並配發 Session 1 , 之後該主機需要更新資料, 都要同時告知目前為 Session 1 .
當玩家 A 透過電腦 乙 登入,由於 Session 表內已經有一個 A 登入,系統必須停止 Session 1 ,或不再配發新的 Session , 以確保同一遊戲內只有一個 A .
當玩家 B 登入,Session 表內無相關資料,系統允許登入,並配發 Session 2 , 之後該主機需要更新資料, 都要同時告知目前為 Session 2 , 達到不同使用者會取得不同資訊.

另外要定期踢除逾時的 Session , 例如每次玩家有動作, 該 Session 會更新最後動作時間, 如果超過 30 分鐘未動作, 就把使用者趕回城鎮, 不然就放玩家站在荒野被砍死.

8
pantc328
iT邦研究生 1 級 ‧ 2012-02-12 21:18:32

算了,不可能會成功
不同的領域,有不同的作法
用socket要寫出大遊戲,大程式,難
不要直接寫用底層方式寫
不要用寫網路資料庫或寫ERP的慨念去做

MS 有很多寫遊戲的Framework 如 XNA,Directx..
用裡面的方式去寫連線才會正確

alice0920 iT邦新手 5 級 ‧ 2012-02-17 00:15:21 檢舉

謝謝你的建議~

8
sula3065408
iT邦研究生 1 級 ‧ 2012-02-13 16:03:15

1.要抽象化遊戲通訊的行為,應該不是叫client直接去存取資料庫,除了安全的理由之外,同步問題及資料量也會變麻煩...

2.Socket server要multi client,理論上應該是要做multi-threaded based Client/Server Socket,先傳入登入資料連線,連線起來之後開出分支的process或是thread處理client要求,server會給client端session number,並且建立以session number索引的連線資料塊,資料塊可以用矩陣、串鏈或是乾脆存取資料庫都行,而是否要鎖定玩家不可以跨session,是另外一回事。而資料回傳會給到非預期的client應該是server端作法有問題,一般來說當server listen port 978(假設),A client連上之後,server要另外派一個port給client A,比如10001,那B連線一樣是先問候port 978,server可能會給出10002給B,以此類推,那server程式對port 10002要求回應的資料自然就不會給到client A,所以multi-thread client/server架構上應該有BUG吧。

3.我想XNA、DirectX...應該不會幫你做這種連線的限制...畢竟怎麼設計是在人爽的事情,Framework不是萬靈藥...好像只幫你橋一些IO、圖形、聲音、、、之類的API,而通訊的部份著墨很少吧,Direct Play好像是udp傳一些比較像是輸入裝置的資料,好像跟什麼登入資料之類東西差很多吧...

alice0920 iT邦新手 5 級 ‧ 2012-02-17 00:17:41 檢舉

您好~我是透過server連結資料庫再傳給client
目前已解決覆蓋掉的問題
謝謝您~

6
godstamp
iT邦新手 3 級 ‧ 2012-02-13 16:33:45

用看看 Photon 吧!!
http://www.exitgames.com/
TCP 和 UDP 都有..
有完整 Server 端應用範例,甚至於 MMORPG 都有...
幾乎直接拿範例套用就能滿足即時遊戲需求,如果需要連接資料庫,只要從 Server 端應用中找出監聽接收資料的 Method 解析收到的資料即可,要將資料庫資料送回給 client 也差不多方式。
不過做遊戲一定會有客制化需求,所以也可以自由設計 server 應用的遊戲邏輯。
免費使用有限制 100 人同時在線,但無使用期限,用來測試及學習的話已綽綽有餘。

alice0920 iT邦新手 5 級 ‧ 2012-02-17 00:21:12 檢舉

謝謝您~您提供的網頁真不錯~

我要發表回答

立即登入回答