Android 에서 socket을 이용한 2인용 게임 개발중이다
소켓을 이용해서 메시지를 두번 보낼 때 빠진 메시지가 있어 Log를 검토해 보았다
game code
if (tempPoint.y < 0 || tempPoint.y > 500) {
isPaused = true
gameData.resetData()
sendMessageToClientViaSocket("SERVER_STOPPED_GAME")
messageCallback.onGameStateMessageFromThread(GameState.STOPPED)
if(tempPoint.y <0) {
sendMessageToClientViaSocket("SERVER_WIN")
messageCallback.onGameWinnerFromThread(true)
} else {
sendMessageToClientViaSocket("CLIENT_WIN")
messageCallback.onGameWinnerFromThread(false)
}
return
}
sendMesssage
fun sendMessageToClientViaSocket(message: String): Unit {
try{
if (connectedSocket != null && connectedSocket?.isConnected == true) {
CoroutineScope(Dispatchers.IO).launch {
outputStream?.write(message.toByteArray())
}
}
} catch(e:Exception) {
Log.e(">>>>","sendMessageToClientViaSocket@serverSocketThread exception : ${e.message}")
}
}
Client의 SocketThread에서 Log를 보면 간간히 한번씩 두개의 Message가 합해져 전달 되고 이것 때문에 정확한 상태 전달이 이루어 지지 않았다
concatenated Log
2024-04-25 13:03:07.409 32518-395 >>>> com.example.lamb0693.p2papp I ClientThread ReceivedMessage : SERVER_STOPPED_GAMESERVER_WIN
2024-04-25 13:03:07.410 32518-395 >>>> com.example.lamb0693.p2papp I onOtherMessageReceivedFromServerViaSocket : SERVER_STOPPED_GAMESERVER_WIN
원래 이렇게 되는 경우가 TCP전달에 있을 수 있다고 하는 것 같다
코드를 수정했다
message를 보낼때 끝에 "\n"을 delimeter 용으로 넣고
fun sendMessageToClientViaSocket(message: String): Unit {
try{
if (connectedSocket != null && connectedSocket?.isConnected == true) {
CoroutineScope(Dispatchers.IO).launch {
val messageWithLF = message + "\n"
outputStream?.write(messageWithLF.toByteArray())
}
}
} catch(e:Exception) {
Log.e(">>>>","sendMessageToClientViaSocket@serverSocketThread exception : ${e.message}")
}
}
client 의 Socket Thread에서는
합쳐져서 올 가능성에 대비해서
message를 delimeter를 기준으로 split하고
split된 message 하나 하나를 처리해 주었다
try{
val bytesRead = inputStream?.read(buffer)
if (bytesRead != null && bytesRead > 0) {
val receivedMessage = String(buffer, 0, bytesRead)
val messages = receivedMessage.split("\n")
for (msg in messages){
if(msg.isNotBlank()){
if(msg.startsWith("GAME_DATA")){
messageCallback.onGameDataReceivedFromServerViaSocket(msg)
} else {
Log.i(">>>>", "ClientThread ReceivedMessage : $msg")
when(msg) {
"SERVER_STARTED_GAME" -> messageCallback.onGameStateFromServerViaSocket(GameState.STARTED)
"SERVER_PAUSED_GAME" -> messageCallback.onGameStateFromServerViaSocket(GameState.PAUSED)
"SERVER_RESTARTED_GAME" -> messageCallback.onGameStateFromServerViaSocket(GameState.STARTED)
"SERVER_STOPPED_GAME" -> messageCallback.onGameStateFromServerViaSocket(GameState.STOPPED)
"SERVER_WIN" -> messageCallback.onGameWinnerFromServerViaSocket(true)
"CLIENT_WIN" -> messageCallback.onGameWinnerFromServerViaSocket(false)
else -> messageCallback.onOtherMessageReceivedFromServerViaSocket(msg)
}
}
}
}
} else {
isRunning = false
}
이렇게 바꾸니 게임이 오류가 발생하거나 빠지는 정보 없이 진행되었다
'AndroidStudio' 카테고리의 다른 글
Wi-fi Aware를 이용한 채팅 앱 제작 (7) (0) | 2024.03.25 |
---|---|
Wi-fi Aware를 이용한 채팅 앱 제작 (6) (0) | 2024.03.24 |
Wi-fi Aware를 이용한 채팅 앱 제작 (5) (0) | 2024.03.24 |
Wi-fi Aware를 이용한 채팅 앱 제작 (4) (0) | 2024.03.24 |
Wi-fi Aware를 이용한 채팅 앱 제작 (3) (0) | 2024.03.24 |