Google Play Services 16.0.0 Realtime Многопользовательская проблема. Одна передача сообщения вызывает сотни onRealTimeMessageReceived
Мы опубликовали приложение в сентябре 2017 года с многопользовательскими играми в режиме реального времени:9.8.0, и оно работает нормально.
Теперь, когда нам нужно перейти на play-services-games:16.0.0, мы столкнулись с серьезными проблемами.
Во время игры игрок отправляет до 70 UnreliableMessage и получает до 210 onRealTimeMessageReceived в секунду для обновления позиций, скоростей и рейтинга. Я проверил в консоли API Google, что это намного ниже пределов моих квот, и в play-services-games все отлично:9.8.0.
Сразу после игрового процесса, игрок отправляет одну трансляцию ReliableMessage, которую он закончил
мой вывод Logcat:
D: 'F' state == 1 multiLVL:1 myVelX:0
D: state: p.getParticipantId(): p.getDisplayName():1 :p_CL-dmtHltfqngwEQAQ :JohnWarrior2006 :p_CL-dmtHltfqngwEQAw :Kostas43
D: state: p.getParticipantId(): p.getDisplayName():1 :p_CL-dmtHltfqngwEQBA :Johnny20061117 :p_CL-dmtHltfqngwEQAw :Kostas43
D: state: p.getParticipantId(): p.getDisplayName():1 :p_CL-dmtHltfqngwEQAg :Nikos2010 :p_CL-dmtHltfqngwEQAw :Kostas43
D: &&& GAME &&&& FinishedPl broadcastScore
но другие игроки получают сотни onRealTimeMessageReceived одного сообщения непрерывно в течение некоторого времени в play-services-games:16.0.0. Эта неисправность не появляется, если я отключаю положение, обновление скоростей во время игры.
мой вывод Logcat:
D: Message received: F thisScore:36698 sender:p_CJHbxo3H8bKE-wEQBA
D: Message received: F thisScore:39910 sender:p_CJHbxo3H8bKE-wEQAw
D: Message received: F thisScore:36698 sender:p_CJHbxo3H8bKE-wEQBA
D: Message received: F thisScore:39910 sender:p_CJHbxo3H8bKE-wEQAw
D: Message received: F thisScore:36698 sender:p_CJHbxo3H8bKE-wEQBA
D: Message received: F thisScore:39910 sender:p_CJHbxo3H8bKE-wEQAw
D: Message received: F thisScore:36698 sender:p_CJHbxo3H8bKE-wEQBA
.............
.............
.............
D: Message received: F thisScore:39910 sender:p_CJHbxo3H8bKE-wEQAw
D: Message received: F thisScore:36698 sender:p_CJHbxo3H8bKE-wEQBA
D: Message received: F thisScore:39910 sender:p_CJHbxo3H8bKE-wEQAw
D: Message received: F thisScore:36698 sender:p_CJHbxo3H8bKE-wEQBA
D: Message received: F thisScore:39910 sender:p_CJHbxo3H8bKE-wEQAw
D: Message received: F thisScore:36698 sender:p_CJHbxo3H8bKE-wEQBA
D: Message received: F thisScore:39910 sender:p_CJHbxo3H8bKE-wEQAw
Если игрок нажимает кнопку, чтобы повторить матч, он посылает одну трансляцию ReliableMessage
мой вывод Logcat:
D: 'R' state == 3 multiLVL:0 myVelX:0
D: state: p.getParticipantId(): p.getDisplayName():3 :p_CL-dmtHltfqngwEQAQ :JohnWarrior2006 :p_CL-dmtHltfqngwEQAw :Kostas43
D: state: p.getParticipantId(): p.getDisplayName():3 :p_CL-dmtHltfqngwEQBA :Johnny20061117 :p_CL-dmtHltfqngwEQAw :Kostas43
D: state: p.getParticipantId(): p.getDisplayName():3 :p_CL-dmtHltfqngwEQAg :Nikos2010 :p_CL-dmtHltfqngwEQAw :Kostas43
D: GAME multiGameBounds > broadcastScore
но снова другие игроки получают сотни onRealTimeMessageReceived одного сообщения непрерывно в течение некоторого времени в play-services-games:16.0.0. Эта неисправность появляется не на всех устройствах.
мой вывод Logcat:
D: (char) buf[0] == 'R':
D: Message received: R thisScore:47262 sender:p_CJHbxo3H8bKE-wEQAw
D: (char) buf[0] == 'R':
D: Message received: R thisScore:47262 sender:p_CJHbxo3H8bKE-wEQAw
D: (char) buf[0] == 'R':
.............
.............
.............
D: (char) buf[0] == 'R':
D: Message received: R thisScore:47262 sender:p_CJHbxo3H8bKE-wEQAw
D: (char) buf[0] == 'R':
D: Message received: R thisScore:47262 sender:p_CJHbxo3H8bKE-wEQAw
D: (char) buf[0] == 'R':
Некоторые соответствующие части кода:
OnRealTimeMessageReceivedListener mOnRealTimeMessageReceivedListener = new OnRealTimeMessageReceivedListener() {
@Override
public void onRealTimeMessageReceived(@NonNull RealTimeMessage realTimeMessage) {
byte[] buf = realTimeMessage.getMessageData();
String sender = realTimeMessage.getSenderParticipantId();
//Log.d(TAG,"ParticipantID: "+sender);
.............
//if (buf[0] != 'F') {
Log.d(TAG, "Message received: " + (char) buf[0] + " thisScore:" + thisScore+" sender:"+sender);
//}
.............
if ((char) buf[0] == 'F') {
int r1st = buf[6] & 0x000000ff;
if (r1st == 1) {
somebody1st = true;
for (int p = 0; p < pls.size(); p++) {
if (pls.get(p).playerId.equals(sender)) {
pls.get(p).multiLevel = true;
}
}
}
int finPosY = buf[5] & 0x000000ff;
for (int i = 0; i < pNUM; i++) {
if (/*finishedPlayers[i].equals(" ") ||*/ !finishedPlayers[0].equals(sender) &&
!finishedPlayers[1].equals(sender) && !finishedPlayers[2].equals(sender) &&
!finishedPlayers[3].equals(sender)) {
if (finishedPlayers[i].equals(" ")) {
finishedPlayers[i] = realTimeMessage.getSenderParticipantId();
playLifeSound++;
Log.d(TAG, "FinishedPl: " + finishedPlayers[i] + " sender:" + sender);
break;
}
}
}
for (int p = 0; p < pls.size(); p++) {
if (pls.get(p).playerId.equals(sender)) {
if (finPosY == 1)
pls.get(p).positionY = 2000;
else
pls.get(p).positionY = 0;
break;
}
}
}
.............
if ((char) buf[0] == 'R') {
rPLA = realTimeMessage.getSenderParticipantId();
Log.d(TAG, "(char) buf[0] == 'R':" );
for (int p = 0; p < pls.size(); p++) {
if (pls.get(p).playerId.equals(sender)) {
pls.get(p).jetSurf = buf[5] & 0x000000ff;
break;
}
}
}
.............
updatePeerScoresDisplay();
}
};
а также:
public void broadcastScore(int state,int myScore,int myCordx,int myCordy,int multiLVL,int myVelX,int myVelY) {
.............
if (state == 1) {
mMsgBuf[0] = (byte) 'F';
mMsgBuf[5] = (byte) multiLVL;
mMsgBuf[6] = (byte) myVelX;
Log.d(TAG,"'F' state == 1 multiLVL:"+multiLVL+" myVelX:"+myVelX);
}
.............
if (state == 3) {
mMsgBuf[0] = (byte) 'R';
mMsgBuf[5] = (byte) multiLVL;
Log.d(TAG,"'R' state == 3 multiLVL:"+multiLVL+" myVelX:"+myVelX);
}
.............
// Send to every other participant.
if (mParticipants != null) {
for (Participant p : mParticipants) {
if (p.getParticipantId().equals(mMyId))
continue;
if (p.getStatus() != Participant.STATUS_JOINED)
continue;
if (leftPL < 3 && mRoomId != null && isSignedIn()) {
if (state != 0 && state != 5) {
// final score notification must be sent via reliable message
Log.d(TAG, "state: p.getParticipantId(): p.getDisplayName():" + state + " :" + p.getParticipantId() + " :" + p.getDisplayName()
+ " :" + mMyId+ " :" + myName);
mRealTimeMultiplayerClient.sendReliableMessage(mMsgBuf,
mRoomId, p.getParticipantId(), new RealTimeMultiplayerClient.ReliableMessageSentCallback() {
@Override
public void onRealTimeMessageSent(int statusCode, int tokenId, String recipientParticipantId) {
//Log.d(TAG, "RealTime message sent");
//Log.d(TAG, " statusCode: " + statusCode);
//Log.d(TAG, " tokenId: " + tokenId);
//Log.d(TAG, " recipientParticipantId: " + recipientParticipantId);
}
})
.addOnSuccessListener(new OnSuccessListener<Integer>() {
@Override
public void onSuccess(Integer tokenId) {
//Log.d(TAG, "Created a reliable message with tokenId: " + tokenId);
}
});
} else {
// it's an interim score notification, so we can use unreliable
mRealTimeMultiplayerClient.sendUnreliableMessage(mMsgBuf, mRoomId, p.getParticipantId());
}
}
}
}
}