手遊登錄和傳統頁遊、端遊有一些區別,要考慮的問題也要比後者多一些,比如:
- 第三方接入sdk的驗證
- 過多第三方sdk帶來的代碼複雜度
- 因網絡不穩定,經常斷線重連等
遊戲登錄過程在玩家的眼裏是非常簡單的,只需要點一下登陸按鈕即可,實際上這個過程沒有想象的那麼簡單,特別是在手遊中,一般會加入第三方渠道sdk之後,就會有些複雜。下面就把這個登錄的整個過程寫下來。
先說明一下手遊登錄過程:1 輸入username和pwd 2 選擇服務器 3 連接服務器玩遊戲
一、第三方登錄sdk
手遊登錄很大一部分的登錄來自於第三方賬戶,比如qq, weibo等等,所以第一步要了解第三方登錄怎麼回事。(其實就是獲取appid 和 app key),接下來會解釋這兩個appid和key是什麼
比如你的app 需要嵌入qq登錄功能,
第一步你需要在qq互聯官網註冊你的app,比如web app,你就需要在qq的sdk開放平臺註冊你的app信息,如下:
信息填寫完成,點擊“確定”後,網站註冊完成,進入管理中心,在管理中心可以查看到網站獲取的appid和appkey,如下圖所示:
到這裏你需要的東西就是app id 和app key,這兩個就代表了你的應用在qq sdk上的關聯情況。
openid是此網站上唯一對應用戶身份的標識,網站可將此ID進行存儲便於用戶下次登錄時辨識其身份,或將其與用戶在網站上的原有帳號進行綁定。
第二步,有了app id 和app key就可以用qq登錄了,用qq登錄成功後會返回:access token以及openid,access token用來判斷用戶在本網站上的登錄狀態
到此步驟,最重要的token就拿到了,這樣就可以開始討論手遊登錄流程了。
二、手遊登錄
手遊登錄組成結構:
1、客戶端
流程:
(1)客戶端輸入渠道賬號user_name和密碼password;
(2) 傳入:app_id、app_key、user_name、password 登錄,登錄SDK成功之後,會返回一個token;
(3)保存token;
說明:
app_id和app_key是遊戲製作方在接入渠道sdk時申請的;user_name和password 好比你的qq帳號或者微博等等
2、web服務器
流程:
(1)客戶端拿着剛纔的token, 向web服務器驗證token是否可以登錄,web服務器會返回SessionId和 遊戲服務器列表
(2) 顯示服務器列表,供用戶選擇
3、遊戲服務器
流程:
(1)客戶端拿着剛纔的sessionid, 以及服務器的ip和port登錄遊戲服務器。服務器返回該用戶在該服務器的玩家主公信息
(2)顯示主公信息決定是新用戶創建主公還是已經有主公,開始玩遊戲了- -
三、登錄流程
登錄流程seq圖
對於前兩步沒什麼好說的,詳細說一下第三步:
client將openid和token,platform去登錄web服務器的時候,web服務器需要根據token和platform去驗證這個openid是不是正確。
具體是:
- web服務器根據platform 來選擇 調用qq的sdk還是weibo的sdk,
- 把openid和token發送給第三方來確定是不是正確的
- 如果正確,根據openid和platform去自己的數據庫中找到本系統的內部user,並且創建該user的session
四、其他問題的思考
1 因爲有很多第三方,導致sdk很多,而且如果sdk更新、意味着app就要更新。其中SDK更新成本是比較容易被忽略的,而由於接入速度過慢的時候產生的收入流失成本則更容易被忽略,所以可以考慮使用 一次性接入的sdk,比如 棱鏡、飛流、TalkingData等等,但是這些sdk到底好不好也值得商榷。
2 關於第三方帳號和本系統內部帳號的關聯重要性的探討,因爲如果第三方sdk連接不上,這樣玩家就不能玩遊戲了,這個代價是非常大的,所以倘若一開始使用第三方登錄後就關聯自己的帳號,這樣即使第三方sdk掛了,用戶還是可以繼續玩的。
3 .....
--------------------------------------------------------華麗分割--------------------------------------------------------
當前後端登錄架構:
一、整體架構圖
現在的設計如下所示,如果這樣不好的話,抓緊噴
二、詳細介紹
整體分爲三部分:1 web集羣,2 session-manager集羣 3 儲存
1 整個web集羣由nginx和tomcat搭建,nginx提供負載均衡,tomcat(多部署幾臺也無妨)負責登錄的驗證處理
2 session-manager 使用的dubbo,(dubbo中使用的zookeeper,至少三臺的zookeeper),因爲web只是負責,具體的處理http請求參數和列服務器列表等等,這些業務比較簡單,沒有什麼性能影響,而session manager定位於服務(SOA), 它可以驗證第三方的token是否正確,管理用戶Session,或者第三方查找內部user等等,這些操作設計db,redis等等,甚至還有user CRUD操作,所以業務比較複雜,但是集羣中每臺機器又相對獨立,所以對於這種業務比較多而且比較重的任務可以做成SOA. 於是有了session manager
3 redis 單純爲了存儲session ,好比當年的memcache, 而db呢,涉及到第三方用戶和內部用戶id的對應。
三、當前部署情況
1 zookeeper部署到88機器上,啓動了3個zk ,端口分別爲 2081,2082,2083
2 nginx部署到88上的80端口。 由於使用的是https協議,所以url: https://xxx.xxx.com:63043/xxx-web/action/user/login 上行參數:openid, token , platform。 可以用web登錄試試:https://xxx.xxx.com:63043/xxx-web/login
登錄代碼:
@CoreAnnotation.PostMethod
public void login(ActionContext ctx) throws IOException {
String openId = ctx.paramStr("openId");//openid
String token = ctx.paramStr("token");//token
String platform = ctx.paramStr("platform");
//各種sdk驗證
boolean validatePlatformOAuthResult = PlatformOAuthService.INSTANCE.validatePlatformOAuth(openId, token, platform);
if(!validatePlatformOAuthResult){
ctx.outputJson("res", -1);
return ;
}
User findUser = UserService.INSTANCE.findUserByOpenIdAndPlatform(openId,platform);
if (findUser == null) {
// 系統錯誤,估計sessionmanager 掛了
ctx.outputJson("res", -1);
} else {
String sessionId = encryptUser(findUser,openId, platform, ctx.ip());
UserService.INSTANCE.registerSession(findUser, sessionId);
CookieService.saveUserInCookie(ctx, findUser, true);
JSONObject json = new JSONObject();
json.put("zonelist", ZoneStateList);
json.put("session", sessionId);
json.put("res", 1);
ctx.print(json);
}
}
3 session-manager 當前只是啓動一臺,部署到88上,路徑 /home/xxx/sessionmanager
4 redis使用的88上 : 10.10.10.88:62031,10.10.10.88:62032 一個主一個從
5 socket登錄接口
message Login {
required string openid = 1;
optional string sessionid = 2;
optional string zoneName = 3;
}