2016-12-01 84 views
0

實際上我使用Netty編寫客戶端 - 服務器程序,但是我陷入了自上週以來無法解決的問題。netty客戶端上的Java輸入

因爲這是一個非常大的項目,我不能粘貼我所有的代碼,但是,我開始使用從Netty中的github上(https://github.com/netty/netty/tree/4.1/example/src/main/java/io/netty/example/securechat

這個例子在遊戲中的背景下,我想,讓玩家輸入他喜歡的每一個命令(改變他的名字,或看看發生了什麼),但事情是,在輸入過程中,我無法收到服務器答案。

服務器答案是通過回調接受:

public class ClientHandler extends SimpleChannelInboundHandler<String> { 

    @Override 
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 
     System.out.println(cause.getMessage()); 
     ctx.close(); 
     System.exit(84); 
    } 

    @Override 
    public void channelRead0(ChannelHandlerContext arg0, String answer) throws Exception { 
     // HERE 
    } 
} 

而在我的主迴路其實我這樣做(我簡化它,因爲它太長):

BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
String line; 
line = in.readLine(); 
// Process and send to server 
System.out.println(line); 

當我等待用戶輸入並同時接收服務器應答,則輸入阻止了我的回調。我只在輸入完成時收到它。

有人能夠賜教嗎?我怎樣才能做出一個非阻塞的輸入或任何其他的東西,當服務器實際上給我一些東西,我可以停止輸入過程,並閱讀答案?

謝謝!

+0

我有點困惑。在用戶輸入之前,您會收到來自服務器的答案? –

+0

實際上,當我在做「line = in.readLine()」時,我很可能會收到服務器的回答,但我無法得到它。例如:有5名玩家。播放器5正在播放,我正在鍵入要發送到服務器的內容。當玩家輪到他時,遊戲(無論什麼原因)結束了:所以遊戲應該從頭開始並通知所有玩家。但是,由於玩家1,2,3和我卡在readLine()過程中,我們無法獲得服務器的通知(回調不被調用,但通常應該)。只有當我們通過readLine部分時,我們纔會得到它。 – NPanda

+0

http://stackoverflow.com/questions/40668791/how-can-a-netty-server-cancel-receiving-a-response-from-a-web-server這可能會幫助你。 –

回答

1

您應該將輸入循環與netty處理程序分離。

如果你從netty處理程序開始你的遊戲輸入循環,這將意味着netty線程永遠不會回到netty的核心,因此你的頻道被標記爲繁忙,這意味着新的輸入將排隊,並且只會在線程返回時處理。

解決這個問題的一個好方法就是讓一個新的線程實例正確的啓動你的程序,並且讓這個線程調用netty的方法去做你的遊戲動作。