2011-10-18 6 views
14

नेटटी ट्यूटोरियल पढ़ने के दौरान, मुझे नेटटी और Google Protocol Buffers को एकीकृत करने के तरीके के बारे में एक सरल description मिला है। मैंने इसके उदाहरण की जांच शुरू कर दी है (क्योंकि दस्तावेज़ीकरण में कोई और जानकारी नहीं है) और उदाहरण के लिए स्थानीय समय आवेदन जैसे एक साधारण आवेदन लिखा है। लेकिन इस उदाहरण PipeFactory कक्षा में स्थिर आरंभीकरण उपयोग कर रहा है, जैसे:नेटटी + प्रोटोबफर: एक कनेक्शन के लिए कुछ संचार संदेश

import org.jboss.netty.channel.ChannelPipeline; 
import org.jboss.netty.channel.ChannelPipelineFactory; 
import org.jboss.netty.handler.codec.protobuf.ProtobufDecoder; 
import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder; 
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; 
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; 

import static org.jboss.netty.channel.Channels.pipeline; 

/** 
* @author sergiizagriichuk 
*/ 
class ProtoCommunicationClientPipeFactory implements ChannelPipelineFactory { 

    public ChannelPipeline getPipeline() throws Exception { 
     ChannelPipeline p = pipeline(); 
     p.addLast("frameDecoder", new ProtobufVarint32FrameDecoder()); 
     p.addLast("protobufDecoder", new ProtobufDecoder(Communication.DataMessage.getDefaultInstance())); 

     p.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender()); 
     p.addLast("protobufEncoder", new ProtobufEncoder()); 

     p.addLast("handler", new ProtoCommunicationClientHandler()); 
     return p; 
    } 

} 

(कृपया लाइन p.addLast("protobufDecoder", new ProtobufDecoder(Communication.DataMessage.getDefaultInstance())); पर एक नज़र डालें) और सिर्फ एक कारखाना है (जैसा कि मैं समझता हूँ) ClientBootstrap वर्ग के लिए बनाया जा सकता है, मैं bootstrap.setPipelineFactory() विधि मतलब । तो, इस स्थिति में मैं सर्वर से प्राप्त करने के लिए ONE संदेश और एक संदेश भेजने के लिए संदेश का उपयोग कर सकता हूं और यह मेरे लिए बुरा है, और मुझे लगता है कि सिर्फ मेरे लिए नहीं :(मैं अलग-अलग संदेशों का उपयोग कैसे कर सकता हूं सिर्फ एक कनेक्शन के लिए? शायद मैं कुछ protobufDecoder इस

p.addLast("protobufDecoder", new ProtobufDecoder(Communication.DataMessage.getDefaultInstance())); 
p.addLast("protobufDecoder", new ProtobufDecoder(Communication.TestMessage.getDefaultInstance())); 
p.addLast("protobufDecoder", new ProtobufDecoder(Communication.SrcMessage.getDefaultInstance())); 

या अन्य तकनीकों की तरह एक बहुत बना सकते हैं? धन्यवाद।

+0

आप पाइपलाइन में कई डिकोडर्स/एन्कोडर्स जोड़ सकते हैं, लेकिन वे डेटा पास करने में सक्षम होना चाहिए जो उन्हें नहीं पता कि उन्हें कैसे संभालना है। [Github पर netty स्रोत] को देख रहे हैं (https://github.com/netty/netty/blob/master/src/main/java/org/jboss/netty/handler/codec/protobuf/ProtobufDecoder.java) ऐसा लगता है यह मामला नहीं है। तो शायद ऐसा करने का एक तरीका है, लेकिन मुझे संदेह है कि यह सरल है। वैसे भी कोशिश करें और परिणाम साझा करें :) – Slartibartfast

+0

@Slartibartfast हाँ, यह आसान नहीं है और कड़ी मेहनत चाहता है :( –

उत्तर

5

मुझे google groups में नेटटी के लेखक का धागा मिला है और मुझे पता चला है कि मुझे अपना आर्किटेक्चर बदलना है या जैसा कि मैंने ऊपर लिखा है, अपना खुद का डिकोडर लिखना है, इसलिए, यह सोचना शुरू करें कि किस तरह से आसान और बेहतर होगा।

+4

मुझे लगता है कि उन समूहों के धागे का बिंदु यह है कि यदि आप कई प्रकार के संदेश भेजना चाहते हैं, तो एक समाधान प्रोटोबफ में 1 सामान्य उद्देश्य "संदेश कंटेनर" (चलो 'प्रोटोकॉल मैसेज') को परिभाषित करना होगा जिसमें 1 या अधिक अलग होगा संदेशों के प्रकार। फिर आप 'प्रोटोकॉल मैसेज' संदेश प्रकार के लिए प्रोटोबफ डिकोडर का उपयोग करेंगे, और नेटटी में संदेश हैंडलर को आगे की व्याख्या छोड़ देंगे। – tmbrggmn

+0

हां, मुझे समझ में आया, धन्यवाद। –

2

सैद्धांतिक रूप से यह सूट करने के लिए प्रत्येक आवक संदेश के लिए पाइप लाइन को संशोधित करके किया जा सकता है आने वाला संदेश। port unification पर एक नज़र डालें नेटटी में उदाहरण।

अनुक्रम होगा:
1) फ्रेम विकोडक या किसी अन्य "DecoderMappingDecoder" में आप) भेजे संदेश
2 का संदेश प्रकार की जांच गतिशील पाइप लाइन को संशोधित रूप में उदाहरण

लेकिन क्यों नहीं में दिखाया गया है विभिन्न कनेक्शन का उपयोग करें और इस अनुक्रम का पालन करें:
1) केवल एक बार आने वाले संदेश के आधार पर पाइपलाइन में अन्य डिकोडर्स जोड़ें।
2) उसी पाइपलाइन में अंतिम हैंडलर के रूप में चैनल अपस्ट्रीम हैंडलर का उदाहरण जोड़ें, इस तरह सभी संदेशों को एक ही उदाहरण में भेज दिया जाता है, जो लगभग एक कनेक्शन होने जैसा होता है।

+0

सैद्धांतिक रूप से हमें डीकोडर से कुछ आईडी पढ़ने और डीकोडिंग के लिए सही एल्गोरिदम का चयन करने के लिए संशोधित करना चाहिए, मैं इस समाधान के बारे में सोचता हूं लेकिन यह नहीं है इसे करने का बस या अच्छा तरीका। मैं सिर्फ एक कनेक्शन क्यों खोलना चाहता हूं, क्योंकि मैं अपने क्लाइंट को सेट अप करना चाहता हूं और सर्वर से कनेक्शन तैयार करना चाहता हूं और सर्वर पर सभी संदेश भेजने के लिए इस (केवल एक) कनेक्शन का उपयोग करना चाहता हूं, जैसे संदेश संचालन, और वर्तमान वास्तुकला मुझे प्रत्येक ऑपरेशन के लिए बहुत से ग्राहकों को बनाने की संभावना प्रदान करता है, मुझे लगता है कि यह अच्छा आईडीईए नहीं है! –

+0

यदि आपके पास एन संदेश प्रकार और एन डीकोड करने के विभिन्न तरीके हैं, तो आप अभी भी उसी कनेक्शन का उपयोग कर सकते हैं एक "मैपिंगडोडर" जो संदेश के प्रकार की जांच करेगा और इसे डीकोड करने के लिए सही डिकोडर पर भेज देगा। नेटटी एम्बेडेड डिकोडर (http://grepcode.com/file/repository.jboss पर एक नज़र डालें .org/maven2/org.jboss.netty/netty/3.1.4.GA/org/jboss/netty/हैंडलर/कोडेक/एम्बेडर/डीकोडरएम्बेडर.जावा) जो आपको पाइपलाइन का उपयोग किए बिना डिकोडर का उपयोग करने का एक तरीका प्रदान कर सकता है। – Abe

1

यह मुद्दा काफी नेटटी सीमा या एन्कोडर/डिकोडर सीमा नहीं है। समस्या यह है कि Google प्रोटोकॉल बफर ऑब्जेक्ट्स को क्रमबद्ध/deserialize करने के लिए एक तरीका प्रदान कर रहे हैं, लेकिन एक प्रोटोकॉल प्रदान नहीं है। उनके पास मानक वितरण के हिस्से के रूप में कुछ प्रकार का आरपीसी कार्यान्वयन है, लेकिन यदि आप अपने आरपीसी प्रोटोकॉल को लागू करने का प्रयास करेंगे तो आप संकेत के 3 परतों के साथ समाप्त हो जाएंगे। मैंने प्रोजेक्ट में से किसी एक में क्या किया है, वह संदेश को परिभाषित करना था जो मूल रूप से संदेशों का एक संघ है। इस संदेश में एक फ़ील्ड है जो टाइप और दूसरा फ़ील्ड है जो वास्तविक संदेश है। आप अभी भी 2 इंडिकेशन परतों के साथ समाप्त हो जाएंगे, लेकिन 3. नहीं। इस तरह नेटटी का उदाहरण आपके लिए काम करेगा, लेकिन जैसा कि पिछले पोस्ट में उल्लेख किया गया था, आपको व्यवसाय तर्क हैंडलर में अधिक तर्क देना होगा।

3

यदि आप अपने स्वयं के कोडेक्स लिखने जा रहे हैं, तो आप कस्टम डेटा ऑब्जेक्ट्स के लिए बाहरी इंटरफ़ेस को कार्यान्वित करना चाहते हैं।

  • सीरियलज़ेबल कम प्रयास है, लेकिन सबसे खराब प्रदर्शन (सबकुछ क्रमबद्ध करता है)।
  • Protobuf प्रयास और प्रदर्शन के बीच एक अच्छा व्यापार बंद है (रखरखाव .proto की आवश्यकता है)
  • Externalizable उच्च प्रयास है, लेकिन सबसे अच्छा प्रदर्शन (कस्टम न्यूनतम कोडेक)

आप पहले से ही पता है अपनी परियोजना होगा पहाड़ बकरी की तरह स्केल करने के लिए, आपको कठिन सड़क पर जाना पड़ सकता है। प्रोटोबफ एक चांदी की बुलेट नहीं है।

2

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

message AnyMessage { 
    message DataMessage { [...] } 
    optional DataMessage dataMessage = 1; 
    message TestMessage { [...] } 
    optional TestMessage testMessage = 2; 
    message SrcMessage { [...] } 
    optional SrcMessage srcMessage = 3; 
} 

वैकल्पिक फ़ील्ड जो सेट ओवरहेड नहीं सेट करते हैं। इसके अतिरिक्त आप एक एनम जोड़ सकते हैं, लेकिन यह सिर्फ एक बोनस है।

0

आप एक संदेश में पेलोड के रूप में विभिन्न प्रकार के संदेश भेजने के लिए संदेश सुरंग का उपयोग कर सकते हैं। आशा है कि

0

लंबे अनुसंधान और पीड़ा के बाद ... मैं संदेशों को एक रैपर संदेश में उपयोग करने के विचार के साथ आया था। उस संदेश के अंदर मैं पर केवल 0 की अनुमति सीमित करने के लिए वन कुंजी का उपयोग करता हूं। उदाहरण का चेकआउट करें:

message OneMessage { 
    MessageType messageType = 1; 

    oneof messageBody { 
     Event event = 2; 
     Request request = 3; 
     Response response = 4; 
    } 

    string messageCode = 5; //unique message code 
    int64 timestamp = 6; //server time 
} 
संबंधित मुद्दे