開(kāi)發(fā)多玩家 Android 游戲時(shí)如何處理連接問(wèn)題
我們開(kāi)發(fā)了一款A(yù)ndroid聊天室應(yīng)用演示,使用了AppWarp(譯注:Appwarp 是創(chuàng)建實(shí)時(shí)多用戶游戲的跨平臺(tái)網(wǎng)絡(luò)引擎),而AppWarp引擎闡明了怎樣處理間歇性的網(wǎng)絡(luò)鏈接故障。這個(gè)演示用到了AppWarp的具有網(wǎng)絡(luò)彈性的API。
為什么需要網(wǎng)絡(luò)彈性: 在移動(dòng)設(shè)備中,數(shù)據(jù)連接一直是一個(gè)問(wèn)題。 當(dāng)用戶在移動(dòng)中,數(shù)據(jù)源將經(jīng)常切換基站,或者在2G和3G之間降級(jí)/升級(jí),或切換WiFi,或由于屏幕鎖定或用戶按下home鍵使得應(yīng)用程序切換到后臺(tái)運(yùn)行。 這對(duì)依賴(lài)持續(xù)數(shù)據(jù)連接的應(yīng)用程序/游戲帶來(lái)影響。AppWarp 提供了 強(qiáng)大的功能 來(lái)處理 網(wǎng)絡(luò)彈性 問(wèn)題, 用戶可以通過(guò)它 在 連接丟失的 情況下,保持 應(yīng)用 之前的 狀態(tài) 。
想知道更多有關(guān)appwarp彈性:點(diǎn)擊這里
包含兩個(gè) Activities 的應(yīng)用
MainActivity: Main Activity 允許用戶連接到AppWarp服務(wù)端。用戶輸入他們的名字然后連接到AppWarp服務(wù)器。為了啟用彈性特性(Resiliency Feature),你應(yīng)該在初始化WarpClient之后設(shè)置默認(rèn)恢復(fù)間隔(Recovery Allowance interval):
- private void init(){
- WarpClient.initialize(Constants.apiKey, Constants.secretKey);
- WarpClient.setRecoveryAllowance(120);
- try {
- theClient = WarpClient.getInstance();
- } catch (Exception ex) {
- Toast.makeText(this, "Exception in Initilization", Toast.LENGTH_LONG).show();
- }
- }
這會(huì)告訴服務(wù)器默認(rèn)恢復(fù)時(shí)間間隔,在這個(gè)時(shí)間內(nèi),即使在連接丟失的情況下,服務(wù)端也不會(huì)銷(xiāo)毀用戶session。我們用AppHq 控制臺(tái)創(chuàng)建了一個(gè)靜態(tài)變量room。一旦連接并注冊(cè)到這個(gè)room,我們就轉(zhuǎn)向ChatActivity。
- public static final String roomId = "1469583531"; // static room id defined in Constant.java
- @Override
- public void onSubscribeRoomDone(RoomEvent event) {
- if(event.getResult()==WarpResponseResultCode.SUCCESS){
- Intent intent = new Intent(this, ChatActivity.class);
- startActivity(intent);
- }else{
- showToastOnUIThread("onSubscribeRoomDone Failed with ErrorCode: "+event.getResult());
- }
- }
ChatActivity.java 這個(gè) Activity 包含了發(fā)送/接收聊天邏輯,并且也管理聊天日志。上半部分包含了同一個(gè)room中參與用戶的列表。綠色的狀態(tài)指示意思是用戶在線,灰色的意思是暫停(臨時(shí)連接錯(cuò)誤)。屏幕下半部分包含了用戶發(fā)送的聊天記錄。在這個(gè)activity的啟動(dòng)后,要想獲取房間中的在線用戶,我們可以調(diào)用
- theClient.getLiveRoomInfo(Constants.roomId);
隨著onGetLiveRoomInfoDone的響應(yīng)動(dòng)作, 我們?cè)谟脩袅斜磉m配器中加入?yún)⑴c用戶。
- public void onGetLiveRoomInfoDone(final LiveRoomInfoEvent event) {
- if(event.getResult()==WarpResponseResultCode.SUCCESS){
- onlineUserList.clear();
- if(event.getJoinedUsers().length>1){// if more than one user is online
- final String onlineUser[] = Utils.removeLocalUserNameFromArray(event.getJoinedUsers());
- for(int i=0;i<onlineUser.length;i++){
- User user = new User(onlineUser[i].toString(), true);
- Log.d(onlineUser[i].toString(), onlineUser[i].toString());
- onlineUserList.add(user);
- }
- resetAdapter();
- }else{
- showToastOnUIThread("No online user found");
- }
- }else{
- showToastOnUIThread("onGetLiveRoomInfoDone Failed with ErrorCode: "+event.getResult());
- }
- }
處理連接彈性:在任何原因任何用戶與AppWarp服務(wù)器連接中斷的情形下,服務(wù)端將維持連接直到預(yù)定義的恢復(fù)時(shí)間,不過(guò)它會(huì)給房間中的其他用戶發(fā)送一個(gè)通知,告知某用戶當(dāng)前處于暫停狀態(tài)。如果用戶在定義的彈性時(shí)間內(nèi)恢復(fù)連接狀態(tài),那么其他用戶將獲得該用戶狀態(tài)繼續(xù)的通知。否則用戶將收到OnUserLeftRoom通知,并且將該用戶從OnlineUser列表中刪除。維護(hù)暫停/繼續(xù)狀態(tài):如果我們使用AppWarp彈性特性,在任何用戶與AppWarp服務(wù)器中斷連接時(shí),我們將收到一個(gè)通知。
- @Override
- public void onUserPaused(String locid, boolean isLobby, String userName) {
- for(int i=0;i<onlineUserList.size();i++){
- User user = onlineUserList.get(i);
- if(user.getName().equals(userName)){
- user.setStatus(false);
- }
- }
- resetAdapter();
- }
- @Override
- public void onUserResumed(String locid, boolean isLobby, String userName) {
- for(int i=0;i<onlineUserList.size();i++){
- User user = onlineUserList.get(i);
- if(user.getName().equals(userName)){
- user.setStatus(true);
- }
- }
- resetAdapter();
- }
恢復(fù)連接:如果用戶的網(wǎng)絡(luò)連接由于某些原因中斷了,比如在2G/3G/WiFi/towers之間進(jìn)行切換,或者其它原因,我們會(huì)在ConnectonRequestListener中得到一個(gè)連接錯(cuò)誤,其錯(cuò)誤代碼為WarpResponseResultCode.CONNECTION_ERROR_RECOVERABLE,通過(guò)檢測(cè)該錯(cuò)誤代碼我們可以調(diào)用恢復(fù)連接的API來(lái)恢復(fù)我們之間的session。我們建議每隔5秒鐘嘗試進(jìn)行一次重新連接。
- theClient.RecoverConnection();
- @Override
- public void onConnectDone(final ConnectEvent event) {
- if(event.getResult() == WarpResponseResultCode.SUCCESS){
- showToastOnUIThread("Connection success");
- }
- else if(event.getResult() == WarpResponseResultCode.SUCCESS_RECOVERED){
- showToastOnUIThread("Connection recovered");
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- if(progressDialog!=null){
- progressDialog.dismiss();
- }
- progressDialog = ProgressDialog.show(ChatActivity.this, "", "Please wait..");
- }
- });
- theClient.getLiveRoomInfo(Constants.roomId);
- }
- else if(event.getResult() == WarpResponseResultCode.CONNECTION_ERROR_RECOVERABLE){
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- progressDialog = ProgressDialog.show(ChatActivity.this, "", "Recoverable connection error. Recovering session after 5 seconds");
- }
- });
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- progressDialog.setMessage("Recovering...");
- theClient.RecoverConnection();
- }
- }, 5000);
- }
- else{
- showToastOnUIThread("Non-recoverable connection error."+event.getResult());
- handleLeaveRoom();
- this.finish();
- }
- }
源代碼可以從我們的 git庫(kù)上進(jìn)行下載或查看。如果你有什么問(wèn)題或者需要進(jìn)一步的幫助,請(qǐng)隨時(shí)跟我們聯(lián)系: support@shephertz.com。