游戲服務(wù)器開發(fā)過程中钧敞,整個(gè)服務(wù)器的架構(gòu)設(shè)計(jì)對于項(xiàng)目的影響是至關(guān)重要的,其中包括登錄流程麸粮,消息機(jī)制流程溉苛,消息加密流程 內(nèi)部服務(wù)器消息跳轉(zhuǎn),定時(shí)任務(wù)等弄诲。centos系統(tǒng)為例愚战,給大家梳理下游戲架構(gòu)的基礎(chǔ)設(shè)計(jì)思想。
如何設(shè)計(jì)
1. 登錄服務(wù)器通信方式:采用http或者h(yuǎn)ttps與游戲客戶端進(jìn)行信
2. 校驗(yàn)數(shù)據(jù)齐遵,游戲客戶端發(fā)過來的數(shù)據(jù)是否正確寂玲,采用DBserver(數(shù)據(jù)庫反向代理)校驗(yàn),異步通信方式RPC
3. 數(shù)據(jù)通信格式:采用json梗摇,返回?cái)?shù)據(jù)也同樣是json
4. 每個(gè)功能采用的都是路由方式訪問拓哟,彼此隔離
流程分析
1. 支持不同登錄的方式,例如:第三方登錄(微信伶授、微博断序、QQ等)流纹,手機(jī)號注冊,游客登錄
2. 每個(gè)玩家登錄成功后违诗,會隨機(jī)生成一個(gè)token捧颅,及代理服務(wù)器的地址(反向代理)
3. 玩家通過2步驟獲取的數(shù)據(jù),主動(dòng)連接代理服務(wù)器的地址较雕,發(fā)送tocken校驗(yàn)數(shù)據(jù)的正確
4. 校驗(yàn)成功碉哑,返回玩家的數(shù)據(jù),同時(shí)進(jìn)入游戲主界面,后端記錄玩家此刻的游戲的狀態(tài)
5. 以上只是粗略的簡述流程,實(shí)際開發(fā)中要復(fù)雜一些
實(shí)例代碼
// 主函數(shù)
func main() {
conf.InitConfig()
DB.DBInit()
http.HandleFunc("/"+conf.GetConfig().Server.URL+"/client/login", Login) // 登錄流程
http.HandleFunc("/"+conf.GetConfig().Server.URL+"/client/register", Login) // 注冊流程
http.HandleFunc("/"+conf.GetConfig().Server.URL+"/server/list", servers) // 獲取區(qū)域列表
http.HandleFunc("/"+conf.GetConfig().Server.URL+"/server/login", GameToken) // 服務(wù)器校驗(yàn)虹蓄,token數(shù)據(jù)流程
err := http.ListenAndServe(conf.GetConfig().Server.HTTPAddr, nil)
if err != nil {
glog.Errorln("http.ListenAndServe()函數(shù)執(zhí)行錯(cuò)誤,錯(cuò)誤為:%v\n", err)
return
}
}
// 登錄操作
func Login(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Accss-Control-Allow-Origin", "*")
req.Header.Add("content-type", "charset=UTF-8")
// 獲取賬號密碼
fmt.Println("req:",req)
if req.Method == "GET" {
if accountable := req.FormValue("AccountName"); accountable != "" {
if accountPw := req.FormValue("AccountPw"); accountPw != "" {
// 獲取玩家數(shù)據(jù)
data := twlib_proto.C2SUserLogin{
AccountName: accountable,
AccountPw: util.MD5_LollipopGO(accountPw),
}
// 發(fā)送給DB sever 去驗(yàn)證數(shù)據(jù)
ulcerate := DbLogin(&data)
fmt.Println(ulcerate)
// token生成的機(jī)制 -- 19位時(shí)間戳 md5
stricken := util.GetNowtimeMD5_LollipopGO() // 時(shí)間19位時(shí)間
GMapUser[stricken] = ulcerate
rcdata := &msg.LoginData{
Token: stricken,
Url: ulcerate.LatestArea, // 默認(rèn)新區(qū),或者近期登錄
ServerList: ulcerate.ServerList, // 30個(gè)區(qū)數(shù)據(jù)(分頁是沒30區(qū)一頁)
}
// 確保登錄正確
if ulcerate.RoleUid > 0 {
rcdata.AesKey = conf.GetConfig().Server.AesKey
}
// 返回客戶端
sendData, _ := json.Marshal(rcdata)
replyJson(w, sendData)
return
}
}
replyJson(w, "parameter is wrong!")
}
}
注意事項(xiàng)
- 登錄服務(wù)器tocken生成邏輯
以LollipopGo分布式游戲架構(gòu)為例:
1. 采用底層庫:LollipopGo/util
2. 調(diào)用方式:util.Md5_LollipopGO(動(dòng)態(tài)的19位時(shí)間)
3. 19位時(shí)間生成函數(shù):util.GetNowUnixNano_LollipopGo()
- 登錄服務(wù)器的數(shù)據(jù)庫設(shè)計(jì)
1. 測試前期登錄服務(wù)器的數(shù)據(jù)庫反向代理可以使用游戲邏輯架構(gòu)中的服務(wù)
2. 預(yù)發(fā)布及上線期間需要分離,也就是登錄服務(wù)器的數(shù)據(jù)和游戲邏輯數(shù)據(jù)不同贮尖,主要是考慮到性能及安全性
3. 登錄服務(wù)器的數(shù)據(jù)庫反向代理服務(wù)器建議增加redis緩存玩家數(shù)據(jù),對應(yīng)的玩家同時(shí)TTL可以設(shè)置