简体   繁体   English

当应用程序进入后台时,实时多人游戏Google Play游戏服务同行会断开连接

[英]Real-time Multiplayer Google Play Games Services peer gets disconnected when app goes in background

I am building a real time multiplayer game using 'Google Play Games Services'. 我正在使用“Google Play游戏服务”构建实时多人游戏。 My question is that when peers are connected to a room and playing the game, and one of them puts their application in background that peer gets disconnected from room, and other peers receives callback of that peer leaving the room, is their a way to prevent this from happening. 我的问题是,当同伴连接到一个房间并玩游戏时,其中一个将他们的应用程序置于后台,同伴与房间断开连接,而其他同伴收到该同伴离开房间的回调,是他们的一种预防方法这发生了。

For testing purpose fragment does not call to leave that room in any of its life cycle methods. 出于测试目的,片段不会调用在任何生命周期方法中离开该房间。

I've added code snippets to provide better understanding. 我添加了代码片段以提供更好的理解。

@Override
    public void onStop() {
        super.onStop();
//        if (mRoomId!=null && !mRoomId.isEmpty()) {
//            Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, mRoomId);
//        }
//        getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
//        mPlaying = false;
    }

        @Override
            public void onActivityResult(int request, int response, Intent data) {
                if (request == RC_SELECT_PLAYERS) {
                    if (response != Activity.RESULT_OK) {
                        // user canceled
                        return;
                    }

                    // get the invitee list
                    Bundle extras = data.getExtras();
                    final ArrayList<String> invitees =
                            data.getStringArrayListExtra(Games.EXTRA_PLAYER_IDS);

                    // get auto-match criteria
                    Bundle autoMatchCriteria = null;
                    int minAutoMatchPlayers =
                            data.getIntExtra(Multiplayer.EXTRA_MIN_AUTOMATCH_PLAYERS, 0);
                    int maxAutoMatchPlayers =
                            data.getIntExtra(Multiplayer.EXTRA_MAX_AUTOMATCH_PLAYERS, 0);

                    if (minAutoMatchPlayers > 0) {
                        autoMatchCriteria = RoomConfig.createAutoMatchCriteria(
                                minAutoMatchPlayers, maxAutoMatchPlayers, 0);
                    } else {
                        autoMatchCriteria = null;
                    }

                    // create the room and specify a variant if appropriate
                    RoomConfig.Builder roomConfigBuilder = makeBasicRoomConfigBuilder();
                    roomConfigBuilder.addPlayersToInvite(invitees);
                    if (autoMatchCriteria != null) {
                        roomConfigBuilder.setAutoMatchCriteria(autoMatchCriteria);
                    }
                    RoomConfig roomConfig = roomConfigBuilder.build();
                    Games.RealTimeMultiplayer.create(((MainActivity) getActivity()).getGoogleApiClient(), roomConfig);

                    // prevent screen from sleeping during handshake
                    getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                }

                if (request == RC_WAITING_ROOM) {
                    if (mWaitingRoomFinishedFromCode) return;

                    if (response == Activity.RESULT_OK) {
                        // (start game)
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                if (getContext()!=null) {
                                    Player[] players = getParticipantPlayers();
                                    if (players!=null && players.length>0) {
                                        startGame(players);
                                    }
                                }
                            }
                        }, 1000);
                    }
                    else if (response == Activity.RESULT_CANCELED) {
                        // Waiting room was dismissed with the back button. The meaning of this
                        // action is up to the game. You may choose to leave the room and cancel the
                        // match, or do something else like minimize the waiting room and
                        // continue to connect in the background.

                        // in this example, we take the simple approach and just leave the room:
                        Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, mRoomId);
                        getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                    }
                    else if (response == GamesActivityResultCodes.RESULT_LEFT_ROOM) {
                        // player wants to leave the room.
                        Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, mRoomId);
                        getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                    }
                }
            }

    private RoomUpdateListener roomUpdateListener = new RoomUpdateListener() {

            @Override
            public void onJoinedRoom(int statusCode, Room room) {
                if (getContext()!=null) {
                    roomCreatorId = room.getCreatorId();
                    mRoomId = room.getRoomId();
                    mParticipants.clear();
                    mParticipants.addAll(room.getParticipants());
    //            setCurrentPlayerParticipantId();
                    if (statusCode != GamesStatusCodes.STATUS_OK) {
                        // let screen go to sleep
                        getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

                        // show error message, return to main screen.
                        Toast.makeText(getContext(), "Error while joining room.", Toast.LENGTH_SHORT).show();
                        showRoomUi();
                    }

                    // get waiting room intent
                    Intent i = Games.RealTimeMultiplayer.getWaitingRoomIntent(((MainActivity) getActivity()).getGoogleApiClient(), room, MIN_PLAYERS);
                    startActivityForResult(i, RC_WAITING_ROOM);
                }
            }

            @Override
            public void onRoomCreated(int statusCode, Room room) {
                if (getContext()!=null) {
                    roomCreatorId = room.getCreatorId();
                    mRoomId = room.getRoomId();
                    mParticipants.clear();
                    mParticipants.addAll(room.getParticipants());
    //            setCurrentPlayerParticipantId();
                    if (statusCode != GamesStatusCodes.STATUS_OK) {
                        // let screen go to sleep
                        getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

                        // show error message, return to main screen.
                        Toast.makeText(getContext(), "Error creating room.", Toast.LENGTH_SHORT).show();
                        showRoomUi();
                    }

                    // get waiting room intent
                    Intent i = Games.RealTimeMultiplayer.getWaitingRoomIntent(((MainActivity) getActivity()).getGoogleApiClient(), room, MIN_PLAYERS);
                    startActivityForResult(i, RC_WAITING_ROOM);
                }
            }


            @Override
            public void onLeftRoom(int i, String s) {
                if (getContext()!=null) {
    // remove the flag that keeps the screen on
                    mRoomId = null;
                }
            }

            @Override
            public void onRoomConnected(int statusCode, Room room) {
                if (getContext()!=null) {
                    roomCreatorId = room.getCreatorId();
                    mRoomId = room.getRoomId();
                    mParticipants.clear();
                    mParticipants.addAll(room.getParticipants());
    //            setCurrentPlayerParticipantId();
                    if (statusCode != GamesStatusCodes.STATUS_OK) {
                        // let screen go to sleep
                        getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

                        // show error message, return to main screen.
                        Toast.makeText(getContext(), "Error connecting to room.", Toast.LENGTH_SHORT).show();
                        showRoomUi();
                    }
                }
            }

        };


        private RoomStatusUpdateListener roomStatusUpdateListener = new RoomStatusUpdateListener() {

            @Override
            public void onRoomConnecting(Room room) {
                if (getContext()!=null) {
                    mParticipants.clear();
                    mParticipants.addAll(room.getParticipants());
                }
            }

            @Override
            public void onRoomAutoMatching(Room room) {
                if (getContext()!=null) {
                    mParticipants.clear();
                    mParticipants.addAll(room.getParticipants());
                }
            }

            @Override
            public void onPeerInvitedToRoom(Room room, List<String> list) {
                if (getContext()!=null) {
                    mParticipants.clear();
                    mParticipants.addAll(room.getParticipants());
                }
            }

            @Override
            public void onPeerJoined(Room room, List<String> list) {
                if (getContext()!=null) {
                    mParticipants.clear();
                    mParticipants.addAll(room.getParticipants());
                }
            }

            @Override
            public void onConnectedToRoom(Room room) {
                if (getContext()!=null) {
                    mMyId = room.getParticipantId(Games.Players.getCurrentPlayerId(((MainActivity) getActivity()).getGoogleApiClient()));
                    mParticipants.clear();
                    mParticipants.addAll(room.getParticipants());
                }
            }

            @Override
            public void onDisconnectedFromRoom(Room room) {

                if (getContext()!=null) {
    // leave the room
                    Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, room.getRoomId());

                    // clear the flag that keeps the screen on
                    getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

                    // show error message and return to main screen
                    Toast.makeText(getContext(), "Network error.", Toast.LENGTH_SHORT).show();

                    showRoomUi();
                }

            }

            @Override
            public void onP2PConnected(String s) {
            }

            @Override
            public void onP2PDisconnected(String s) {
            }

            @Override
            public void onPeersConnected(Room room, List<String> peers) {
                if (getContext()!=null) {
                    mParticipants.clear();
                    mParticipants.addAll(room.getParticipants());
                    if (mPlaying) {
                        // add new player to an ongoing game
                    } else if (shouldStartGame(room)) {
                        // start game!
                    }
                }
            }

            @Override
            public void onPeersDisconnected(Room room, List<String> peers) {
                if (getContext()!=null) {
                    mParticipants.clear();
                    mParticipants.addAll(room.getParticipants());
                    if (mPlaying) {
                        // do game-specific handling of this -- remove player's avatar
                        // from the screen, etc. If not enough players are left for
                        // the game to go on, end the game and leave the room.
                    }
                    else if (shouldCancelGame(room)) {
                        // cancel the game
                        Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, room.getRoomId());
                        getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                        showRoomUi();
                    }
                }
            }

            @Override
            public void onPeerLeft(Room room, List<String> peers) {
                if (getContext()!=null) {
                    mParticipants.clear();
                    mParticipants.addAll(room.getParticipants());
                    // peer left -- see if game should be canceled
                    if (!mPlaying && shouldCancelGame(room)) {
                        Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, room.getRoomId());
                        getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                        showRoomUi();
                    }
                }
            }

            @Override
            public void onPeerDeclined(Room room, List<String> peers) {
                if (getContext()!=null) {
                    mParticipants.clear();
                    mParticipants.addAll(room.getParticipants());
                    // peer declined invitation -- see if game should be canceled
                    if (!mPlaying && shouldCancelGame(room)) {
                        Games.RealTimeMultiplayer.leave(((MainActivity) getActivity()).getGoogleApiClient(), roomUpdateListener, room.getRoomId());
                        getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
                        showRoomUi();
                    }
                }
            }

        };

        private RealTimeMessageReceivedListener realTimeMessageReceivedListener = new RealTimeMessageReceivedListener() {
            @Override
            public void onRealTimeMessageReceived(RealTimeMessage realTimeMessage) {
                if (getContext()!=null) {
                    if (realTimeMessage.isReliable()) {
                        handleReliableMessages(realTimeMessage.getMessageData());
                    }
                }
            }
        };

Any help is appreciated. 任何帮助表示赞赏。 Thank you. 谢谢。

AFAIK, that's just how the API was designed and is working as intended. AFAIK,这就是API的设计方式和工作方式。

As mentioned in this documentation , you should leave the active room whenever your game goes into the background. 如本文档中所述 ,每当游戏进入后台时,您应该离开活动室。

For additional insights (from Bruno Oliveira ), you may want to see these related SO posts: 有关其他见解(来自Bruno Oliveira ),您可能希望查看这些相关的SO帖子:

Though, you may also opt to try this suggested solution . 不过,您也可以选择尝试这种建议的解决方案 Try editing BaseGameActivity.onStop() and remove gamehelper.onStop() . 尝试编辑BaseGameActivity.onStop()并删除gamehelper.onStop() With this, gamesclient will only stopped in onDestroy . 有了这个, gamesclient将只停在onDestroy It might be a good option but I haven't actually tried it. 这可能是一个不错的选择,但我还没有尝试过。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Google Play 游戏服务实时多人游戏 - Google Play Games Services Real Time Multiplayer 如何在使用Google Play游戏服务的实时多人游戏中使用僵尸玩家? - How can I use bot players in real-time multiplayer games using Google Play game services? 如何使用Google Play游戏在实时多人游戏中处理应用版本? - How to handle app versions in real-time multiplayer using Google Play Games? 如果Google Play游戏服务提供实时多人游戏,那么使用gamesparks.com有什么优势? 两者有什么区别? - If Google Play Games Services offer Real-time Multiplayer, what is the advantage of using gamesparks.com? What is the difference between these two? 如何检测客户是否故意在Google Play游戏实时多人游戏中留下房间? - How to detect if client intentionally left Room in Google Play Games Real-time Multiplayer? Unity-关闭WaitingRoomUI()方法上的Google Play游戏服务实时多人游戏? - Unity - Google Play Games Services Real Time Multiplayer on close WaitingRoomUI() method? Google Play服务实时多人消息 - Google Play Services Real Time Multiplayer Message 实时多人游戏 - Google Play 服务 - Real time MultiPlayer - Google Play services 实时多人Google Play服务 - real time multiplayer google play services 如何在实时多人Google Play游戏服务中创建房间时向其他参与者发送数据 - How to send data to other participant on Room creation in Real-time Multiplayer Google Play Game Services
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM