這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
如有錯誤的地方,請同仁指正,非常感謝
第一種方式:
共3個進程
Login: 登陸服(同時用於聊天系統) socket長串連
Game: 遊戲服(遊戲邏輯處理) http短串連
Mysql: 資料庫回寫 socket
用戶端socket串連login,保持長串連,驗證成功後,向game服以http方式請求資料
game服向login服http方式驗證該用戶端是否已經正常登陸, 1: 沒有登入則,game返回資料給客戶,沒有登入狀態. 2: 已經登陸,則game返回所需資料給用戶端.
game將修改後的資料以sql語句形式發送給mysql服,同時記錄當前sql到檔案中用於備查.
使用單獨login服的好處在於 用戶端可以一直保持串連,並且login服邏輯處理少. 伺服器壓力小.同時在game服有問題需要閃斷時,還能繼續保持玩家登陸狀態,在緊急更新game服後,用戶端不需要重新串連登陸遊戲. 並且因為login較少的邏輯處理, 各個socket共存串連能力相應變強.可以提高同時線上玩家數. 使用socket串連,便於服務端主動向用戶端發送聊天,公告等資訊. 與game服串連方式不同,主要是因為兩個進程間功能不同導致.
game服使用http方式,http處理能力相較於socket更好,使用更方便,基本不需要去考慮網路連接的狀態問題.用戶端需要什麼資料,可以直接Get請求. 對於每次請求資料,都是單獨一個go程, http並發處理也會更好.
具體實現:
login服唯讀取玩家的Account資訊用於驗證.不產生新sql資料. 如果新使用者登陸,則產生一份臨時資料用於表示新使用者登陸成功.返回給用戶端一個uid.作為用戶端登陸的標記. 用戶端向game服請求資料時,再由game產生sql資料,同時get方式通知login服臨時資料為永久資料. sql語句通知mysql服回寫資料.
用戶端每次向game請求資料都需要帶上參數uid, game服使用uid向login服通過http方式驗證用戶端是否已經登陸成功. 1:沒有登入則提醒登陸 2.已經登陸,則處理邏輯資料 (這裡有個問題,game與login直接的驗證會非常頻繁)
game服的資料處理,則使用記憶體共用方式.
game服啟動時將mysql資料庫中的資料全部讀取到記憶體中. 結構如下:
type UserData struct{//單個玩家的結構資料
Account Account //單個玩家的帳號資訊,元寶,銅錢等屬性
Bag []Bag //單個玩家的背包物品資料. 多個物品
Friend []Friend //單個玩家的好友 多個好友
....
mu sync.RWMutex //單個玩家的資料鎖
}
UserDatas = make(map[int32]UserData) //全服所有玩家資料
type Shop struct{ //商店表 配置表
....
}
ShopInfo = make(map[int32] Shop) //商店的配置表資料
......
說明a: 玩家的資訊,統一放在UserData中,多條資料使用slice結構,盡量減少"對象"數量.
不能統一的資料則單獨一個結構.
game服在遊戲過程中,只要資料變化則產生最佳化後的sql語句,通知mysql服回寫到資料庫
mysql服只負責接收sql語句, 並寫入到資料庫,記錄下當前寫成功的sql語句第幾條.用於資料出錯時. 對比sql檔案,已經寫到哪一條語句.便於恢複資料庫. 如果一旦資料回寫錯誤,則停止接下去的語句回寫, 需要記錄下後續語句的數量即可, 並馬上通知dba管理員.
說明b: 如果一個玩家操作需要影響到其它玩家,則由game服請求login服,由login服主動通知用戶端資料.免去了用戶端定時請求某些操作的麻煩.
例如: A玩家在地圖上移動,需要通知周邊其它玩家,A玩家新的座標點. 此時由game服請求login服,login服通知線上玩家A的新資料.
第二種方式:
純http串連.
game服: http串連
mysql服:資料回寫處理.
A玩家向game請求登陸,game驗證成功後,記錄A玩家登陸成功,並返回給用戶端uid.則此後3分鐘都認為該uid的玩家處於登陸狀態. A用戶端每次請求資料都更新A玩家的最後時間.
其中uid為加密後的資料. 每次重新驗證則產生不同的uid.
純http的弊端: 伺服器不能即時通知用戶端資訊.
遊戲中建立玩家資料更新標誌位. 如A玩家定時2-5秒請求公告標誌位,發現公告標誌位是新的,則讀取.
A玩家移動,需要通知其它周邊玩家, 則向其它玩家的移動處理隊列中添加新資料,並更新通知標誌位, B玩家每1-2秒請求檢查標誌位狀態,有新資料則擷取.
以上兩種方式,其中資料轉送該加密的方式則需要加密.
本人新手,求達人指正