老項目是netty3的,本來想直接改到netty5,但是netty5居然是只支持jdk1.7,很奇怪jdk1.6和jdk1.8都不行..為了兼容jdk1.6加上netty4本來和netty5就差別不大,最后上的netty4.
先期看了一些netty3升netty4的經驗總結,然后開始動工.改完后運行一下,發現2個客戶端連接,只有1個工作正常,另一個在建立連接的時候直接就阻塞到建立連接這里:
channel = this.lastWriteFuture.awaitUninterruptibly().channel();建立連接階段直接一直阻塞,當時我就有點暈啊..死鎖?第一印象,這項目線程無數,理了一遍又一遍真是一點頭緒沒有.隨便寫個簡單demo型的客戶端連接一下,一切正常,服務端沒有任何問題.
對比其中能正常建立連接的客戶端代碼,沒發現什么區別啊(實際上此時如果頭腦快的話,應該已經能定位問題所在了),沒解了,被這問題 絆住1天多,只好用最笨的辦法排除了,從demo代碼向項目中的真實代碼一點一點累加,看出在哪部分..經過n長時間終于確認到這個客戶端的handler部分有問題..這handler繼承了一層,父子類看了一遍又一遍,也沒看出來特別的地方.沒招繼續用最笨的方法,一段代碼一段代碼注釋掉,看哪部分影響..就這樣n久之后發現問題代碼段,一看還沒覺得有什么問題,點了一下看了一下文檔說明才發覺問題所在,感覺這2天又虛度了..
//netty3的方法
@Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { xxxx; }
//netty4我改成的方法 @Override public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPRomise future) throws Exception { xxxx; }
這個當時替換的時候直接當做一個方法處理了...生成新的重寫方法的時候,因為名字很像就直接也點選生成了,然后就把原來的channelConnected方法中的實現寫到這個方法中了.這個其實如果它要是拋異常或是出錯應該馬上就能發現這里寫錯了..但是點選這個connect方法能看到文檔如下解釋:
Calls ChannelHandlerContext.connect(SocketAddress, SocketAddress, ChannelPromise) to forward to the next ChannelOutboundHandler in the ChannelPipeline. Sub-classes may override this method to change behavior.
//簡單說程序在管道中多個ChannelOutBoundHandler中傳遞的時候,可以用這個方法進行一些自定義操作.
然后我把這個方法寫成別的了,而且并沒有調用connect(ctx, remoteAddress, localAddress, future)方法導致這個方法功能直接廢了,沒法在管道中傳遞了.現象就是沒有任何異常和報錯的這個連接走到這里就無返回值的結束了,而建立連接那頭還在無限期的等待連接建立...
@Override public void channelActive(ChannelHandlerContext ctx) throws Exception { xxxx; }改成以上的正常代碼后,功能恢復正常,連接可以正常建立...
新聞熱點
疑難解答