Reputation: 873
I have implemented a two player game with thread pool of sockets. each player connects to their own thread. I added a message Queue system according to this article.
Problem is the messages are lagging. the first respond from the first player is added to messageQueue as expected. But second player doesn't received it by calling poll()
it only receives null yet.
And then the second player responds the second player receives the first players message. My intention is to send the message to second player before his/her response.
I must be doing some mistake or I have neglected some important concept.
Can you please help me find it?
My Code goes like this, there are two Classes related to this, GameRunnable.java and Game.java. I have omitted some code to simplify this mess.
In GameRunnable class ;
public static final Map<GamerRunnable, BlockingQueue<String>> messageQueues = new ConcurrentHashMap<>();
public static final Map<String, GamerRunnable> gameQueue = new ConcurrentHashMap<>();
private Game game;
public void run() {
System.out.println
(this.setGameInstance(clientSocket, readerIn, output) ? "OK": "FAILED");
messageQueues.put(this, new ArrayBlockingQueue<String>(100));
// If player 1
this.game.initGame(this);
// If Player 2
this.game.initGame(this);
}
public static GamerRunnable getGameThreadByName(String name) {
return gameQueue.get(name);
}
public String getName() {
return this.name;
}
in Game.java
public Game(Socket clientSocket, BufferedReader readIn, OutputStream output) {
this.sockGamer = clientSocket;
try {
this.out = output;
this.inGamer = readIn;
} catch(Exception e) {
e.printStackTrace();
}
public void sendToGamer(String msg) {
try {
this.out.write((msg+"\n").getBytes());
this.out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void initGame(GamerRunnable game) {
try {
boolean messageLoop = true;
String line1 = null;
String line2 = null;
while (messageLoop) {
line1 = inGamer.readLine();
if (line1 != null) {
System.out.println("Gamer says: "+line1);
GamerRunnable gamer2 = null;
if (game.getName().equals("red")) {
gamer2 = GamerRunnable.getGameThreadByName("black");
}
else if (game.getName().equals("black")) {
gamer2 = GamerRunnable.getGameThreadByName("red");
}
if (gamer2 != null) {
System.out.println("Adding to Queue");
GamerRunnable.messageQueues.get(gamer2).offer(line1);
}
}
line2 = GamerRunnable.messageQueues.get(game).poll();
if (line2 != null) {
//receiving from Queue
System.out.println(line2);
game.getGameInstance().sendToGamer(line2);
}
}
Upvotes: 0
Views: 133
Reputation: 2765
Due to network latency you may need a short delay to wait for the first message to arrive on the queue. Try poll(time, unit) instead. This will wait for the specified time for a message to appear on the queue. If nothing is there it will return a null like poll() is now. A user will probably not notice a 500ms to 1s delay if no message is available.
Upvotes: 1