हम एक आवेदन जिसका सार्वजनिक प्रोटोकॉल Google प्रोटोकॉल बफ़र पर आधारित है में क्रमबद्धता और संदेशों के अक्रमांकन के लिए Protobuf शुद्ध उपयोग कर रहे हैं। पुस्तकालय उत्कृष्ट है और इसके अलावा हमारी सभी आवश्यकताओं को शामिल करता है: संदेश वास्तव में धारावाहिक होने से पहले हमें बाइट्स में क्रमबद्ध संदेश लंबाई को खोजने की आवश्यकता है।Protobuf शुद्ध संदेश धारावाहिक आकार संपत्ति
The question पहले से डेढ़ साल पहले ही पूछा जा चुका है और मार्क के अनुसार, ऐसा करने का एकमात्र तरीका मेमोरीस्ट्रीम को क्रमबद्ध करना था और .Length
संपत्ति को बाद में पढ़ना था। यह हमारे मामले में स्वीकार्य नहीं है, क्योंकि मेमोरीस्ट्रीम दृश्यों के पीछे एक बाइट बफर आवंटित करता है और हमें इससे बचना होगा।
आप स्पष्ट यदि यूज-केस है, मुझे यकीन है कि हम इसे आसानी से उपलब्ध करा सकते हैं (यदि:
एक ही प्रतिक्रिया से यह पंक्ति हमें आशा है कि यह सब के बाद संभव हो सकता है देता है यह पहले से नहीं है)।
यहाँ हमारे उपयोग है। हमारे पास संदेश हैं जिनके आकार में कई बाइट्स और दो मेगाबाइट्स के बीच भिन्नता है। आवेदन पूर्व-आवंटित बाइट बफर सॉकेट ऑपरेशंस के लिए उपयोग किया जाता है और सीरियलाइजिंग/deserializing के लिए और एक बार गर्म अप चरण खत्म हो जाने के बाद, कोई अतिरिक्त बफर बनाया जा सकता है (संकेत: जीसी और ढेर विखंडन avoding)। बाइट बफर अनिवार्य रूप से पूल किए जाते हैं। हम जितना संभव हो बफर/धाराओं के बीच बाइट कॉपी करने से बचना चाहते हैं।
हम दो संभव रणनीतियों के साथ आए हैं और उन दोनों को संदेश आकार अग्रिम की आवश्यकता होती है: (बड़े) निश्चित-आकार बाइट बफ़र्स
- उपयोग और सभी संदेशों को एक बफर में फिट कर सकते हैं क्रमानुसार;
Socket.Send
का उपयोग कर बफर की सामग्री भेजें। हमें पता होना चाहिए कि अगला संदेश बफर में फिट नहीं हो सकता है और धारावाहिक को रोक सकता है। संदेश आकार के बिना, इसे प्राप्त करने का एकमात्र तरीकाSerialize
के दौरान होने वाले अपवाद की प्रतीक्षा करना है। - (छोटे) परिवर्तनीय आकार बाइट बफर का उपयोग करें और प्रत्येक संदेश को एक बफर में क्रमबद्ध करें;
Socket.Send
का उपयोग कर बफर की सामग्री भेजें। पूल से उपयुक्त आकार के साथ बाइट बफर को देखने के लिए, हमें यह जानने की जरूरत है कि एक धारावाहिक संदेश कितने बाइट करता है।
क्योंकि प्रोटोकॉल पहले ही परिभाषित है (हम इसे नहीं बदल सकते हैं) और Varint32 होने के लिए संदेश लंबाई उपसर्ग की आवश्यकता है, हम SerializeWithLengthPrefix
विधि का उपयोग नहीं कर सकते हैं।
तो यह एक तरीका है कि एक धारा में क्रमांकन के बिना संदेश आकार का अनुमान जोड़ने के लिए संभव है? यदि यह ऐसा कुछ है जो लाइब्रेरी के मौजूदा फीचर सेट और रोडमैप में फिट नहीं है, लेकिन यह करने योग्य है, तो हम पुस्तकालय को विस्तारित करने में रुचि रखते हैं। यदि कोई है तो हम वैकल्पिक दृष्टिकोण की भी तलाश कर रहे हैं।
लंबाई उपसर्ग और SerializeWithLengthPrefix के बारे में: विधि बेस 128, फिक्स्ड 32 और फिक्स्ड 32 बिग इंडियन के रूप में एन्कोड किए गए उपसर्ग लिख सकती है, लेकिन यह Varint32 प्रकार का समर्थन नहीं करती है। हमारा प्रोटोकॉल निम्न संदेश संरचना को परिभाषित करता है: [टाइप: varint32] [लंबाई: varint32] [वास्तविक प्रोटोबफ संदेश]। –
@ बोरीस जो फ़ील्ड-नंबर ** के साथ बिल्कुल आधार-128 है ** ** है। फ़ील्ड-नंबर === प्रकार होगा (शायद एक >> 3 शिफ्ट के साथ)। मुझे * सटीक बाइट्स * देखना होगा, लेकिन यह शायद प्रयोग योग्य है। यदि नहीं, तो मैन्युअल रूप से प्रकार जोड़ें, और आधार-128 और फ़ील्ड 0 का उपयोग करके एन्कोड करें (जो फ़ील्ड नंबर छोड़ देगा) –
स्पष्टीकरण के लिए धन्यवाद, मुझे लगता है कि मुझे वह याद आया। और विस्तृत प्रतिक्रिया के लिए धन्यवाद। हम अभी भी संभावित दृष्टिकोण का मूल्यांकन कर रहे हैं और यथासंभव छोटे डेटा जॉगलिंग और बफर आवंटन के साथ इष्टतम तरीके खोजने की कोशिश कर रहे हैं। –