1
我正在實現帶有服務器套接字機制的多人遊戲。流中的套接字服務器流消息是混合的
- 遊戲運行在一個循環機制。
- 服務器僅向每個連接的播放器播放任何消息。
- 服務器爲每個連接的播放器創建線程
- 消息是JSON,它們每100ms從客戶端發送一次。
- 消息正在被服務器廣播,客戶端沒有間隔讀取。
這是服務器循環:
while (true) {
try {
System.out.println("LISTENING...");
Socket clientSocket = serverSocket.accept();
System.out.println("GOT CONNECTION");
PlayerThread playerThread = new PlayerThread(clientSocket);
playerThread.start();
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Exception occured on server");
break;
}
}
這是PlayerThread循環:
while (true) {
try {
String inputMessage = in.readUTF();
System.out.println("GOT: " + inputMessage);
JsonNode jsonNode = objectMapper.readTree(inputMessage);
String senderName = jsonNode.get("senderName").asText();
if (!players.contains(this)) {
playerName = senderName;
players.add(this);
}
for (PlayerThread p : players) {
p.getOut().writeUTF(inputMessage);
}
最後收聽郵件:
public void listen() {
if (connected) {
try {
if (in.available() > 0) {
String inputMessage = in.readUTF();
System.out.println("GOT MESSAGE: " + inputMessage);
handleMessages(inputMessage);
}
} catch (IOException e) {
LOGGER.log(Level.INFO, "Connection lost");
connected = false;
}
} else
LOGGER.log(Level.INFO, "Player is not connected");
}
上述方法在主遊戲運行循環。它檢查inputStream中是否有內容,然後讀取它。
這是信息如何正確的樣子:
GOT MESSAGE: {"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 52","posX":10.0,"posY":5.0}
當有2名球員它工作正常,但更多的玩家連接更多的可能是得到這樣的消息(或similiar破消息):
在消息LIKGOT MESSAGE: 0} U{"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 65","posX":10.0,"posY":5.0}
或
GOT MESSAGE: {"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 24","pos
有不同的錯誤在一行中是Y字母,半個消息或多個消息。爲什麼會發生這種事?它看起來像有更多的玩家,並且他們在服務器端寫入輸出流時,這個流還沒有被讀取,所以他們正在追加和追加。但這並不能解釋爲什麼會出現破碎和最重要的問題,如何解決它?
我可以移動閱讀流到另一個線程,因爲in.readUTF()鎖定的過程,但我想保持它在遊戲主循環同步的,我不認爲這將有助於(我錯了?)
我試了一下:同步(這){p.getOut()writeUTF(inputMessage);}我認爲原因可以將Java套接字實現躺在裏面也許我使用錯誤類型的流? –
同步(this)將不起作用,因爲每個這是PlayerThread的不同實例。你需要在*全局/共享*對象上同步 – ControlAltDel
你是對的,我改變它在流本身上同步後,它看起來更好。有性能問題,但我不確定它是由多個Java應用程序運行還是通過同步引起的。 –