fix sync issue
parent
5ce406f376
commit
a2cbc5d3af
|
@ -40,6 +40,17 @@ public class Client implements Runnable {
|
||||||
|
|
||||||
view.printGameMenu();
|
view.printGameMenu();
|
||||||
}
|
}
|
||||||
|
ArrayList<Long> removes = new ArrayList<>();
|
||||||
|
for (HashMap.Entry<Long, Message.Sent> message : sentMessages.entrySet()){
|
||||||
|
Message.Sent sent = message.getValue();
|
||||||
|
if (!sent.isAcknowledged() && sent.getTimeSinceSent().get() > Server.MAX_PACKET_ACK_TIME_SECONDS) {
|
||||||
|
System.out.println("The server did not acknowledge our message, did they receive it?");
|
||||||
|
sendMessage(sent);
|
||||||
|
removes.add(message.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Long l : removes)
|
||||||
|
sentMessages.remove(l);
|
||||||
}
|
}
|
||||||
clientSocket.close();
|
clientSocket.close();
|
||||||
}
|
}
|
||||||
|
@ -57,14 +68,19 @@ public class Client implements Runnable {
|
||||||
long clientID = stream.readLong();
|
long clientID = stream.readLong();
|
||||||
long messageID = stream.readLong();
|
long messageID = stream.readLong();
|
||||||
|
|
||||||
|
System.out.println("Receiving message with ID " + messageID + " to client: " + clientID + " of type " + packetID);
|
||||||
|
|
||||||
switch (packetID) {
|
switch (packetID) {
|
||||||
case PacketTable.ACK:
|
case PacketTable.ACK:
|
||||||
Message.Sent message = sentMessages.get(messageID);
|
Message.Sent message = sentMessages.get(messageID);
|
||||||
if (message == null)
|
if (message == null)
|
||||||
throw new RuntimeException("Server message sync error!");
|
throw new RuntimeException("Server acknowledged a message we never sent! (" + messageID + ")");
|
||||||
message.acknowledged();
|
message.acknowledged();
|
||||||
sentMessages.remove(messageID);
|
sentMessages.remove(messageID);
|
||||||
System.out.println("Message acknowledged " + messageID);
|
System.out.println("Message acknowledged with ID: " + messageID);
|
||||||
|
System.out.println("Messages left: " + sentMessages.size());
|
||||||
|
for (HashMap.Entry<Long, Message.Sent> ms : sentMessages.entrySet())
|
||||||
|
System.out.println("MessageID: " + ms.getKey());
|
||||||
break;
|
break;
|
||||||
case PacketTable.DISCONNECT:
|
case PacketTable.DISCONNECT:
|
||||||
running = false;
|
running = false;
|
||||||
|
@ -78,10 +94,12 @@ public class Client implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendMessage(Message.Sent message){
|
private void sendMessage(Message.Sent message){
|
||||||
|
if (message.getMessageID() != PacketTable.ACK)
|
||||||
sentMessages.put(message.getMessageID(), message);
|
sentMessages.put(message.getMessageID(), message);
|
||||||
byte[] data = message.getData().toByteArray();
|
byte[] data = message.getData().toByteArray();
|
||||||
DatagramPacket sendPacket = new DatagramPacket(data, data.length, serverAddress, Server.SERVER_PORT);
|
DatagramPacket sendPacket = new DatagramPacket(data, data.length, serverAddress, Server.SERVER_PORT);
|
||||||
try {
|
try {
|
||||||
|
System.out.println("Sending message with ID " + message.getMessageID() + " to server from: " + message.getClientID() + " of type " + message.getPacketID());
|
||||||
clientSocket.send(sendPacket);
|
clientSocket.send(sendPacket);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.rmi.ServerException;
|
import java.rmi.ServerException;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
@ -33,6 +34,8 @@ public class Server implements Runnable {
|
||||||
socket = new DatagramSocket(SERVER_PORT);
|
socket = new DatagramSocket(SERVER_PORT);
|
||||||
ioThread = new Thread(this);
|
ioThread = new Thread(this);
|
||||||
ioThread.start();
|
ioThread.start();
|
||||||
|
|
||||||
|
mainEngine = new GameEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run(){
|
public void run(){
|
||||||
|
@ -50,21 +53,25 @@ public class Server implements Runnable {
|
||||||
long clientID = stream.readLong();
|
long clientID = stream.readLong();
|
||||||
long messageID = stream.readLong();
|
long messageID = stream.readLong();
|
||||||
|
|
||||||
|
System.out.println("Receiving message with ID " + messageID + " to client: " + clientID + " of type " + packetID);
|
||||||
|
|
||||||
ConnectedClient client = clients.get(clientID);
|
ConnectedClient client = clients.get(clientID);
|
||||||
|
|
||||||
// the server must handle connection requests while the client's processing thread will handle all other messages
|
// the server must handle connection requests while the client's processing thread will handle all other messages
|
||||||
if (packetID == PacketTable.CONNECT){
|
if (packetID == PacketTable.CONNECT){
|
||||||
clients.put(++clientAssignmentID, new ConnectedClient(socket, mainEngine, clientID, messageID, receivePacket.getAddress(), receivePacket.getPort()));
|
long cid = ++clientAssignmentID;
|
||||||
} else if (packetID == PacketTable.DISCONNECT) {
|
System.out.println("A client has connected, his clientID is " + cid);
|
||||||
|
clients.put(cid, new ConnectedClient(socket, mainEngine, cid, messageID, receivePacket.getAddress(), receivePacket.getPort()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (client == null)
|
if (client == null)
|
||||||
throw new ServerException("Client disconnected with invalid client id! (" + clientID + ")");
|
throw new ServerException("Client disconnected with invalid client id! (" + clientID + ")");
|
||||||
|
if (packetID == PacketTable.DISCONNECT) {
|
||||||
client.halt();
|
client.halt();
|
||||||
clients.put(clientID, null);
|
clients.remove(clientID);
|
||||||
} else {
|
continue;
|
||||||
if (client == null)
|
|
||||||
throw new ServerException("Client message with invalid client id! (" + clientID + ")");
|
|
||||||
client.handleRequest(new Message.Received(packetID, clientID, messageID, stream, receivePacket.getData()));
|
|
||||||
}
|
}
|
||||||
|
client.handleRequest(new Message.Received(packetID, clientID, messageID, stream, receivePacket.getData()));
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -104,7 +111,7 @@ public class Server implements Runnable {
|
||||||
processingThread = new Thread(this);
|
processingThread = new Thread(this);
|
||||||
processingThread.start();
|
processingThread.start();
|
||||||
gameEngineThread = new Thread(() -> {
|
gameEngineThread = new Thread(() -> {
|
||||||
while (true) {
|
while (running) {
|
||||||
if (this.allowUpdate.get()) {
|
if (this.allowUpdate.get()) {
|
||||||
engine.updateMap(clientMap);
|
engine.updateMap(clientMap);
|
||||||
}
|
}
|
||||||
|
@ -131,6 +138,7 @@ public class Server implements Runnable {
|
||||||
if (message == null)
|
if (message == null)
|
||||||
throw new RuntimeException("A message was acknowledged but does not exist!");
|
throw new RuntimeException("A message was acknowledged but does not exist!");
|
||||||
message.acknowledged();
|
message.acknowledged();
|
||||||
|
sentMessages.remove(request.getMessageID());
|
||||||
break;
|
break;
|
||||||
case PacketTable.MESSAGE:
|
case PacketTable.MESSAGE:
|
||||||
System.out.println(request.getReader().readUTF());
|
System.out.println(request.getReader().readUTF());
|
||||||
|
@ -153,22 +161,28 @@ public class Server implements Runnable {
|
||||||
}
|
}
|
||||||
requestLock.unlock();
|
requestLock.unlock();
|
||||||
|
|
||||||
|
ArrayList<Long> removes = new ArrayList<>();
|
||||||
for (HashMap.Entry<Long, Message.Sent> message : sentMessages.entrySet()){
|
for (HashMap.Entry<Long, Message.Sent> message : sentMessages.entrySet()){
|
||||||
if (message.getValue().getTimeSinceSent().get() > MAX_PACKET_ACK_TIME_SECONDS) {
|
Message.Sent sent = message.getValue();
|
||||||
System.out.println("The server did not process our message, did they receive it?");
|
if (!sent.isAcknowledged() && sent.getTimeSinceSent().get() > MAX_PACKET_ACK_TIME_SECONDS) {
|
||||||
sendMessage(message.getValue());
|
System.out.println("The client did not acknowledge our message, did they receive it?");
|
||||||
|
sendMessage(sent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Long l : removes)
|
||||||
|
sentMessages.remove(l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(Message.Sent message){
|
public void sendMessage(Message.Sent message){
|
||||||
|
if (message.getMessageID() != PacketTable.ACK)
|
||||||
this.sentMessages.put(message.getMessageID(), message);
|
this.sentMessages.put(message.getMessageID(), message);
|
||||||
byte[] data = message.getData().toByteArray();
|
byte[] data = message.getData().toByteArray();
|
||||||
if (data.length > PACKET_SIZE)
|
if (data.length > PACKET_SIZE)
|
||||||
throw new RuntimeException("Unable to send packet as it exceeds maximum packet size!");
|
throw new RuntimeException("Unable to send packet as it exceeds maximum packet size!");
|
||||||
DatagramPacket request = new DatagramPacket(data, data.length, address, port);
|
DatagramPacket request = new DatagramPacket(data, data.length, address, port);
|
||||||
try {
|
try {
|
||||||
|
System.out.println("Sending message with ID " + message.getMessageID() + " to client: " + message.getClientID() + " of type " + message.getPacketID());
|
||||||
serverSocket.send(request);
|
serverSocket.send(request);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
Loading…
Reference in New Issue