2012-02-15 10 views
5

मेरे पास खिलौना नेटटी सर्वर है और जब मैं अपने चैनलों पर कुछ भी नहीं हुआ तो ग्राहकों को दिल की धड़कन संदेश भेजने की कोशिश कर रहा हूं। मैं इसका परीक्षण कर रहा हूं सर्वर से टेलनेटिंग, एक संदेश लिखना और फिर कुछ भी नहीं भेजना, लेकिन मुझे कोई सुनवाई नहीं मिली!नेटटी इडलेस्टेट हैंडलर के साथ समस्या - क्या मैं इसे गलत तरीके से जांच रहा हूं?

कंसोल:

>>telnet localhost 6969 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
>>foo 
Did you say 'foo'? 

MyPipelineFactory.java

public class MyPipelineFactory implements ChannelPipelineFactory { 
    private final Timer timer; 
    private static final ChannelHandler stringDecoder = new StringDecoder(); 
    private static final ChannelHandler stringEncoder = new StringEncoder(); 
    private final ChannelHandler idleStateHandler; 

    public MyPipelineFactory(Timer t) { 
     this.timer = t; 
     this.idleStateHandler = new IdleStateHandler(timer, 5, 5, 5); 
    } 

    public ChannelPipeline getPipeline() { 
     // create default pipeline from static method 
     ChannelPipeline pipeline = Channels.pipeline(); 
     pipeline.addLast("idleStateHandler", this.idleStateHandler); // heartbeat 
     pipeline.addLast("framer", new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter())); 
     //pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024,0,1)); // get header from message 
     pipeline.addLast("stringDecoder", stringDecoder); 
     pipeline.addLast("stringEncoder", stringEncoder); 
     pipeline.addLast("ServerHandler", new ServerHandler()); // goes at the end 

     return pipeline; 
    } 
} 

HeartbeatHandler.java

public class HeartbeatHandler extends IdleStateAwareChannelHandler { 

    @Override 
    public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) { 
     if (e.getState() == IdleState.READER_IDLE) { 
      System.out.println("Reader idle, closing channel"); 
      //e.getChannel().close(); 
      e.getChannel().write("heartbeat-reader_idle"); 
     } 
     else if (e.getState() == IdleState.WRITER_IDLE) { 
      System.out.println("Writer idle, sending heartbeat"); 
      e.getChannel().write("heartbeat-writer_idle"); 
     } 
     else if (e.getState() == IdleState.ALL_IDLE) { 
      System.out.println("All idle, sending heartbeat"); 
      e.getChannel().write("heartbeat-all_idle"); 
     } 
    } 
} 

फिक्स्ड:

मैं हार्टबीट हैंडलर भूल गया था, जिसके लिए IdleStateHandler की आवश्यकता होती है (यह हिस्सा मेरे लिए स्पष्ट नहीं था)। यह काम करता है।

public class MyPipelineFactory implements ChannelPipelineFactory { 
    private final Timer timer; 
    private static final ChannelHandler stringDecoder = new StringDecoder(); 
    private static final ChannelHandler stringEncoder = new StringEncoder(); 
    private final ChannelHandler idleStateHandler; 
    private final ChannelHandler heartbeatHandler; 

    public MyPipelineFactory(Timer t) { 
     this.timer = t; 
     this.idleStateHandler = new IdleStateHandler(timer, 5, 5, 5); 
     this.heartbeatHandler = new HeartbeatHandler(); 
    } 

    public ChannelPipeline getPipeline() { 
     // create default pipeline from static method 
     ChannelPipeline pipeline = Channels.pipeline(); 
     pipeline.addLast("idleStateHandler", this.idleStateHandler); 
     pipeline.addLast("heartbeatHandler", this.heartbeatHandler); // heartbeat 
     pipeline.addLast("framer", new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter())); 
     //pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024,0,1)); // get header from message 
     pipeline.addLast("stringDecoder", stringDecoder); 
     pipeline.addLast("stringEncoder", stringEncoder); 
     pipeline.addLast("ServerHandler", new ServerHandler()); // goes at the end 

     return pipeline; 
    } 
} 

उत्तर

9

आप ChannelPipeline में HeartbeatHandler जोड़ने के लिए याद किया। आपको IdleStateHandler और हार्टबीट हैंडलर को चैनलपलाइन पर काम करने की आवश्यकता है।

+1

आह, जो उन दोनों दस्तावेज़ों से स्पष्ट नहीं था जिन्हें मुझे दोनों की आवश्यकता है। धन्यवाद – nflacco

+0

क्या यह हो सकता है कि हार्टबीट हैंडलर की अब 3.5.9 में आवश्यकता नहीं है? –

+0

आपको अभी भी –

1

नॉर्मन का जवाब वास्तव में सहायक है, लेकिन मैं एक और चीज़ को इंगित करना चाहता हूं: idleStateHandler और दिल की धड़कन हैंडलर चैनल विशिष्ट होना चाहिए, इसलिए पाइपलाइन फैक्ट्री में, आपको इन दोनों हैंडलरों को निजी सदस्यों के रूप में नहीं बनाना चाहिए, लेकिन getPipeline() विधि में नए बनाने की जरूरत है। यदि आपको उन्हें रिलीज़ करने की आवश्यकता है, तो आपके द्वारा बनाए गए चैनलों को सहेजने के लिए आपके पास एक चैनल मैप भी है, आप टाइमर को संसाधनों को रिलीज़ करने के लिए बेहतर तरीके से रोक देंगे।

+0

क्योंकि IdleStateHandler साझा करने योग्य है मुझे नहीं लगता कि आपको प्रत्येक पाइपलाइन के लिए एक नया उदाहरण बनाने की आवश्यकता है। – WorM

संबंधित मुद्दे