2012-01-28 9 views
8

मैं ज्यादातर नेटटी के साथ हूं लेकिन एक अवधारणा अभी भी मुझे बता रही है, और मुझे ट्यूटोरियल्स में कुछ भी नहीं मिला है। सबसे पहले मैं समझता हूं कि नेटी असीमित है, लेकिन क्लाइंट को सर्वर पर कॉल करने और हैंडलर से परे प्रतिक्रिया प्राप्त करने में सक्षम होना चाहिए। मुझे और समझाएं।नेटटी - क्लाइंट में सर्वर प्रतिक्रिया कैसे प्राप्त करें

मेरे पास एक ग्राहक है जैसा कि नीचे दिखाया गया है। और कृपया ध्यान दें कि मैं समझता हूं कि यह बूटस्ट्रैप किया गया है और प्रत्येक कॉल पर एक नया कनेक्शन स्थापित किया गया है, जो कि उदाहरण को छोटा और अधिक संक्षिप्त बनाने के लिए है। कृपया उस तथ्य को अनदेखा करें।

Client.java

// ServerResponse is a result from the server, in this case 
// a list of users of the system (ignore that each time it's all bootstrapped). 

public User[] callServerForInformationFromGUIWidget() 
{ 
    ClientBootstrap bootstrap = new ClientBootstrap(...); 
    bootstrap.setPipelineFactory(...); 

    ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port)); 
    Channel channel = future.awaitUninterruptibly().getChannel(); 

    // Where request is a POJO sent to the server, 
    // with a request such as get me a list of users 
    RequestPojo request = new RequestPojo(requestUserListCommand); 

    ChannelFuture lastWriteFuture = channel.write(request); 

    if(lastWriteFuture != null) 
     lastWriteFuture.awaitUninterruptibly(); 
} 

अब मैं समझता हूँ सर्वर पर डेटा प्राप्त करने के लिए है, और परिणाम वापस आग। एकमात्र चीज यह है कि मैं इसे क्लाइंट साइड पर कैसे संभाल सकता हूं?

ClientHandler.java

@Override 
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) 
{ 
    User[] users = (User[])e.getMessage(); 
} 

समस्या कैसे ग्राहक कोड वास्तव में उस परिणाम प्राप्त करता है: हाँ ClientHandler वर्ग निम्नलिखित की तरह कुछ कर सकते हैं? सभी उदाहरण एक चैट सेवा के समान हैं, जहां ईवेंट उस क्लाइंट पर कुछ और निकाल देता है जो प्रतिक्रिया पर इंतजार नहीं कर रहा है। यहां तक ​​कि http क्लाइंट उदाहरण में मुझे कमी आई है। कुल मिलाकर दस्तावेज वास्तव में अच्छा है, लेकिन कॉलबैक कैसे करें इस पर कमी है। वैसे भी, इस मामले में मुझे सर्वर से प्रतिक्रिया प्राप्त करने के लिए क्लाइंट की आवश्यकता है, और परिणामों के आधार पर यह वही करेगा जो इसकी आवश्यकता है।

दूसरे शब्दों में, मैं कैसे ग्राहक को इस तरह कुछ करने के लिए लिख सकता हूँ:

IdealClient.java

// ServerResponse is a result from the server, in this case 
// a list of users of the system. 

public User[] callServerForInformationFromGUIWidget() 
{ 
    ... 
    RequestPojo request = new RequestPojo(requestUserListCommand); 
    ChannelFuture lastWriteFuture = channel.write(request); 

    if(lastWriteFuture != null) 
     lastWriteFuture.awaitUninterruptibly(); 

    User[] users = resultFromCallToServer(); 

    performSomeAction(users); 
} 

क्योंकि हैंडलर पता नहीं है जो इस सवाल का जवाब है, या जो की तलाश में है सवाल पूछा। और अगर यह हैंडलर में किया गया है, तो कैसे?

उदाहरणों के बारे में मेरी टिप्पणियों पर वापस, http क्लाइंट (और हैंडलर) उदाहरण केवल System.out पर परिणाम डंप करें। यदि आपके पास एक जीयूआई है तो आप अपने अनुरोध से जीयूआई तक परिणाम कैसे पारित करेंगे? मैंने इसके लिए कभी भी कोई उदाहरण नहीं देखा।

उत्तर

5

जेस्टन सही है। मेरे मामले में मेरे पास एक ग्राहक है जिसके लिए मूल्य टिक डेटा को संसाधित करने की आवश्यकता है। मैं पार्सिंग के लिए Antlr का उपयोग करें। मैं अपने पार्सर में अपनी घटनाओं को आग लगाता हूं, लेकिन मेरे मामले में मेरा प्रोटोकॉल स्ट्रिंग आधारित है। नीचे Antlr के बिना एक उदाहरण है, मैं आपके मामले में स्ट्रिंग संदेश पास करता हूं यह उपयोगकर्ता हो सकता है।

//----------------- Event -------------- 
public class DataChangeEvent { 
    private String message; 

    public DataChangeEvent(String message) { 
     this.message = message; 
    } 

    public String getMessage() { 
     return message; 
    } 


} 

//----------------- Listener -------------- 
public interface DataChangeListenter { 
    public void dataChangeEvent(DataChangeEvent event); 
} 

//----------------- Event Handler that fires the dataChange events -------------- 
// This class needs to be static since you need to register all your classes that want to be notified of data change events 
public class DataChangedHandler { 
    private static List<DataChangeListenter> listeners = new ArrayList<DataChangeListenter>(); 

    public static void registerDataChangeListener(DataChangeListenter listener) { 
     listeners.add(listener); 
    } 

    public static void fireDataChange(DataChangeEvent dataChangeEvent) { 
     for(DataChangeListenter listenter : listeners) { 
      listenter.dataChangeEvent(dataChangeEvent); 
     } 
    } 
} 

//----------------- Example class that implements the listener and registers itself for events -------------- 
public class ProcessMessage implements DataChangeListenter { 

    public ProcessMessage() { 
     DataChangedHandler.registerDataChangeListener(this); 
    } 

    public void dataChangeEvent(DataChangeEvent event) { 
     //Depending on your protocal, I use Antlr to parse my message 
     System.out.println(event.getMessage()); 
    } 


} 

//---------------- Netty Handler ----------- 
public class TelnetClientHandler extends SimpleChannelHandler { 

    private static final Logger logger = Logger.getLogger(TelnetClientHandler.class.getName()); 

    @Override 
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { 
     String message = (String) e.getMessage(); 
     DataChangedHandler.fireDataChange(message); 
    } 
} 
+0

मैं श्रोताओं को पंजीकृत करने के लिए अपने दिशानिर्देश का पालन करने की कोशिश कर रहा हूं लेकिन मुझे "असंगत प्रकार: स्ट्रिंग को डेटाChangeEvent में परिवर्तित नहीं किया जा सकता" ... क्या गलत है? धन्यवाद। – Phobox

1

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

यह काफी कुछ था जो मैं कहने की कोशिश कर रहा था। आपका हैंडलर PipelineFactory जो वहाँ से हैंडलर के लिए मानकों को पारित करने के लिए आसान है में बन जाता है:

bootstrap.setPipelineFactory(new ChannelPipelineFactory() { 
     public ChannelPipeline getPipeline() throws Exception { 
      ChannelPipeline pipeline = Channels.pipeline(); 

      pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.nulDelimiter())); 
      pipeline.addLast("decoder", new XMLDecoder()); 
      pipeline.addLast("encoder", new XMLEncoder()); 
      // notice here I'm passing two objects to the Handler so it can 
      // call the UI. 
      pipeline.addLast("handler", new MyHandler(param1, param2)); 

      return pipeline; 
     } 
    }); 

जब आप अपने पाइपलाइन बनाने आप एक नए कनेक्शन पर अपने हैंडलर जोड़ देंगे। बस एक या अधिक ऑब्जेक्ट्स को पास करें जो इसे यूआई या नियंत्रक को वापस संवाद करने की अनुमति देता है।

+0

तो उदाहरण के लिए, http क्लाइंट उदाहरण में परिणाम केवल System.out पर डाला गया है। क्या होगा यदि आपके पास जीयूआई था तो आपको परिणाम पास करना पड़ा? उदाहरण के लिए इसे एक JTextArea तक पारित किया जाना था कि हैंडलर को पता नहीं है, या शायद एक जेडियलॉग इत्यादि। दूसरे शब्दों में, एक जेबटन दबाया जाता है और ईवेंट क्लाइंट के माध्यम से सर्वर को कॉल करता है। आप मूल रूप से जेबटन की कॉलिंग विधि तक सर्वर से परिणाम कैसे पास करते हैं। –

+0

जोड़ने के लिए, क्योंकि जेबटन हैंडलर JTextArea में परिणाम प्रदर्शित कर सकता है, शायद यह एक जेडियलॉग होगा, –

+1

आप हॉटबोटाओ एसिच मोड जैसे प्रतिक्रियाओं को संभालने के लिए कॉलबैक (श्रोताओं) का उपयोग करना चाहते हैं http://hotpotato.biasedbit.com /, (जो नेटटी का भी उपयोग करता है), तो आपको संदेश के अंदर इसे संभालना होगा :), मुझे लगता है कि इस तरह के कॉलबैक डिफ़ॉल्ट रूप से उपलब्ध नहीं हैं क्योंकि वे प्रोटोकॉल के लिए अधिक विशिष्ट हैं/कौन सा एप्लिकेशन करता है? –

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