开发多玩家Android 游戏时如何处理连接问题

我们开发了一款Android聊天室应用演示,使用了AppWarp(译注:Appwarp 是创建实时多用户游戏的跨平台网络引擎),而AppWarp引擎阐明了怎样处理间歇性的网络链接故障。这个演示用到了AppWarp的具有网络弹性的API。
为什么需要网络弹性在移动设备中,数据连接一直是一个问题。 当用户在移动中,数据源将经常切换基站,或者在2G和3G之间降级/升级,或切换WiFi,或由于屏幕锁定或用户按下home键使得应用程序切换到后台运行。 这对依赖持续数据连接的应用程序/游戏带来影响。AppWarp 提供了 强大的功能 来处理 网络弹性 问题, 用户可以通过它  连接丢失的 情况下,保持 应用 之前的 状态  

包含两个 Activities 的应用 

MainActivity: Main Activity 允许用户连接到AppWarp服务端。用户输入他们的名字然后连接到AppWarp服务器。为了启用弹性特性(Resiliency Feature),你应该在初始化WarpClient之后设置默认恢复间隔(Recovery Allowance interval):
代码片段,双击复制
01
02
03
04
05
06
07
08
09
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();
    }
}

这会告诉服务器默认恢复时间间隔,在这个时间内,即使在连接丢失的情况下,服务端也不会销毁用户session。我们用AppHq 控制台创建了一个静态变量room。一旦连接并注册到这个room,我们就转向ChatActivity。
代码片段,双击复制
01
02
03
04
05
06
07
08
09
10
11
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 这个 Activity 包含了发送/接收聊天逻辑,并且也管理聊天日志。上半部分包含了同一个room中参与用户的列表。绿色的状态指示意思是用户在线,灰色的意思是暂停(临时连接错误)。屏幕下半部分包含了用户发送的聊天记录。在这个activity的启动后,要想获取房间中的在线用户,我们可以调用
代码片段,双击复制
01
theClient.getLiveRoomInfo(Constants.roomId);

随着onGetLiveRoomInfoDone的响应动作, 我们在用户列表适配器中加入参与用户。
代码片段,双击复制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
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());
    }
}</i></i></i>

处理连接弹性:在任何原因任何用户与AppWarp服务器连接中断的情形下,服务端将维持连接直到预定义的恢复时间,不过它会给房间中的其他用户发送一个通知,告知某用户当前处于暂停状态。如果用户在定义的弹性时间内恢复连接状态,那么其他用户将获得该用户状态继续的通知。否则用户将收到OnUserLeftRoom通知,并且将该用户从OnlineUser列表中删除。维护暂停/继续状态:如果我们使用AppWarp弹性特性,在任何用户与AppWarp服务器中断连接时,我们将收到一个通知。
代码片段,双击复制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
@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();
}

恢复连接:如果用户的网络连接由于某些原因中断了,比如在2G/3G/WiFi/towers之间进行切换,或者其它原因,我们会在ConnectonRequestListener中得到一个连接错误,其错误代码为WarpResponseResultCode.CONNECTION_ERROR_RECOVERABLE,通过检测该错误代码我们可以调用恢复连接的API来恢复我们之间的session。我们建议每隔5秒钟尝试进行一次重新连接。
代码片段,双击复制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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库 上进行下载或查看。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值