我已经实现了一个带有线程池套接字的双人游戏。每个玩家都连接到自己的线程。我根据this文章添加了一个消息队列系统。
问题是消息滞后。第一个播放器的第一个响应按预期添加到messageQueue。但是第二个玩家没有通过调用poll()
来接收它,它只接收null。
然后第二个玩家响应第二个玩家接收第一个玩家消息。我的目的是在他/她的回复之前将消息发送给第二位玩家。
我一定是犯了一些错误,或者我忽略了一些重要的概念。
你能帮我找到吗?
我的代码是这样的,有两个与此相关的类,GameRunnable.java和Game.java。我省略了一些代码来简化这个混乱。
在GameRunnable类中;
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;
}
在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);
}
}
答案 0 :(得分:1)
由于网络延迟,您可能需要短暂的延迟才能等待第一条消息到达队列。请尝试使用poll(time, unit)。这将等待消息显示在队列中的指定时间。如果没有,它将返回null,如poll()现在。如果没有可用消息,用户可能不会注意到500毫秒到1秒的延迟。