2011-06-02 7 views
9

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

क्या क्लाइंट बनाने के लिए सामान्य उपयोग है, उस पर एक विधि कॉल करें, फिर इसे बंद करें?

यदि आप कनेक्शन का दोबारा उपयोग करना चाहते हैं तो क्या होगा? उस पर सीमाएं क्या हैं? क्या आप विभिन्न धागे से एक साथ कॉल कर सकते हैं? यदि आप नहीं कर सकते हैं, तो क्या आपको अपना कनेक्शन पूलिंग करना है? और कनेक्शन का दोबारा उपयोग करते समय, क्या आपको कॉल करने से पहले कनेक्शन स्थिति की जांच करनी होगी और इसे गलत तरीके से साफ़ करना होगा?

उत्तर

16

वैसे यह एक साथ बहुत सारे प्रश्न हैं और स्थिति वास्तव में थोड़ा जटिल है। जब आप कोई ग्राहक बनाते हैं तो आप इसे सेवा संदर्भ के माध्यम से कर सकते हैं और ClientBase<ServiceContract> से प्राप्त कक्षा प्राप्त कर सकते हैं या आप ChannelFactory<ServiceContract> का उपयोग कर सकते हैं और मैन्युअल रूप से चैनल बना सकते हैं (पूर्व मामला आंतरिक रूप से चैनलफ़ैक्टरी का उपयोग करता है)।

यह आपके प्रश्न से कैसे संबंधित है? आइए पहले वास्तविक टीसीपी कनेक्शन देखें। जब आप NetTcpBinding को परिभाषित करते हैं तो आप इसकी MaxConnections संपत्ति सेट कर सकते हैं (डिफ़ॉल्ट 10 है)। यह संपत्ति पूल किए गए कनेक्शन की संख्या को परिभाषित करती है। इसका मतलब है कि यदि आप सर्वर पर क्लाइंट चैनल बनाते हैं और चैनल बंद करते हैं तो कनेक्शन तुरंत समाप्त नहीं होता है। यह तब तक पूल में खोला जाता है जब तक कि इसे उसी सर्वर पर किसी अन्य खुले क्लाइंट चैनल द्वारा या उसके निष्क्रिय टाइमआउट की अवधि समाप्त होने तक उपयोग नहीं किया जाता है। सर्वर के रूप में आप कई कनेक्शन खोल सकते हैं लेकिन MaxConnections द्वारा परिभाषित केवल संख्या को क्लाइंट चैनल बंद करने के बाद पूल किया जाएगा। अन्य कनेक्शन तुरंत समाप्त कर दिए जाएंगे। यदि आप CustomBinding बनाते हैं तो आप सीधे टीसीपी परिवहन का उपयोग कर सकते हैं जहां आप निष्क्रिय टाइमआउट को नियंत्रित भी कर सकते हैं (मुझे लगता है कि डिफ़ॉल्ट 2 मिनट है)। जब तक संबंधित ChannelFactory नष्ट नहीं होता है तब तक कनेक्शन को पूल किया जाता है = प्रति एप्लिकेशन ChannelFactory का उपयोग करें (ClientBase इसे आंतरिक रूप से करें)।

अब चैनल के बारे में बात करते हैं क्योंकि यह आपके अन्य प्रश्नों से संबंधित है। डब्ल्यूसीएफ सत्रपूर्ण और सत्र रहित चैनलों को अलग करता है। TcpTransportChannel सत्रपूर्ण है। इसका मतलब है कि एक बार जब आप चैनल खोलते हैं तो आप एक सत्र बनाते हैं। सत्र का अर्थ है कि एकल क्लाइंट प्रॉक्सी से सभी अनुरोध डिफ़ॉल्ट रूप से उसी सेवा उदाहरण (प्रति सत्र इंस्टेंसिंग) द्वारा परोसा जाता है। लेकिन उदाहरण डिफ़ॉल्ट रूप से एकल धागा है। इसका मतलब है कि आपके पास एक ही प्रॉक्सी का उपयोग करके एकाधिक थ्रेड हो सकते हैं लेकिन सेवा अनुक्रमिक क्रम में अनुरोधों को संभाल लेगी। यदि आप अपनी सेवा को एक से अधिक अनुरोध संसाधित करना चाहते हैं तो आपको इसे [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple] के साथ चिह्नित करना होगा। एक बार ऐसा करने के बाद आप सेवा में थ्रेड सुरक्षित प्रसंस्करण के लिए ज़िम्मेदार होते हैं (एक ही सेवा उदाहरण तक पहुंचने वाले एकाधिक थ्रेड)।

सत्रपूर्ण चैनलों का एक बड़ा नुकसान होता है। सेवा पर कोई भी विफलता या अपवाद चैनल को तोड़ देगा और आप चैनल को फिर से उपयोग करने का प्रयास करने के बाद आमतौर पर इसके बारे में जानेंगे (अपवाद यह कह रहा है कि चैनल गलती की स्थिति में है और इसका उपयोग नहीं किया जा सकता है)। आपको इन परिस्थितियों को हमेशा सही तरीके से संभालना होगा और जब आप उन्हें उपयोग नहीं करना चाहते हैं या उन्हें दोषी ठहराए जाने के बाद उन्हें निरस्त करना होगा तो आपको चैनल/प्रॉक्सी को सही ढंग से बंद करना होगा। दोषपूर्ण चैनल की मरम्मत नहीं की जा सकती - इसे निरस्त किया जाना चाहिए और आपको एक नया प्रॉक्सी/चैनल बनाना होगा। मुझे यकीन नहीं है कि यदि पूल ऐसा नहीं करते हैं तो कनेक्शन पूल पर वापस आते हैं।

प्रॉक्सी/चैनल का उपयोग करने से आपके द्वारा बनाए जा रहे एप्लिकेशन के प्रकार पर निर्भर करता है। मैं निश्चित रूप से वेब एप्लिकेशन में एकाधिक अनुरोधों के बीच प्रॉक्सी/चैनल का पुन: उपयोग नहीं करता लेकिन पुन: उपयोग करना WinForm या WPF अनुप्रयोग में बिल्कुल ठीक है।

संपादित करें:

हाँ ClientBaseChannelFactory आंतरिक रूप से उपयोग करता है। जिस तरह से ChannelFactory का उपयोग समय के साथ बदल गया है। .NET 3.0 में कारखाना प्रत्येक ClientBase उदाहरण के लिए बनाया गया था। चूंकि .NET 3.5 डब्ल्यूसीएफ आंतरिक रूप से एमआरयू कैश (हाल ही में उपयोग किया जाता है) का उपयोग करता है जो 32 तक कैश करता है जो आखिरकार कारखानों का उपयोग करता है। इस कैशिंग का लाभ उठाने के लिए आपको पैरामीटर के बिना या endpointConfigurationName और remoteAddress/EndpointAddress के साथ प्रॉक्सी कन्स्ट्रक्टर का उपयोग करना होगा। आपको कोड में एंडपॉइंट नहीं बनाना चाहिए - ये प्रॉक्सी कैश का उपयोग नहीं करती हैं। विषय के बारे में अधिक जानकारी here है।

+1

कि बहुत जानकारीपूर्ण गया था, धन्यवाद। –

+0

लाडस्लावा, यदि एक डब्ल्यूसीएफ सेवा सत्र मोड = NotAllowed के साथ परिभाषित किया गया है, तो क्या इसका मतलब है कि उस सेवा के लिए ग्राहक सेवा प्रॉक्सी को बंद करने की आवश्यकता नहीं है? –

+0

@ ऑटर: यदि सेवा 'सत्र मोड = NotAllowed' के साथ परिभाषित की गई है, तो आप net.tcp सहित किसी भी सत्रत्मक चैनल का उपयोग नहीं कर सकते हैं। आपको प्रॉक्सी को हमेशा बंद या निरस्त करना चाहिए। यह 'आईडीस्पोजेबल' लागू करता है - एक बार जब आप इसे देखते हैं तो आपको हमेशा इसका सामना करना चाहिए। –

0

क्या आप क्लाइंट साइड पर अपनी सेवा प्रॉक्सी बंद कर रहे हैं?

IService service = channelFactory.CreateChannel(); 

service.DoStuff(); 

((IContextChannel) service).Close(); 

यह सभी डब्ल्यूसीएफ ग्राहकों पर लागू होता है, भले ही बाध्यकारी टीसीपी है या नहीं।

अधिक जानकारी के लिए देखें: http://msdn.microsoft.com/en-us/library/aa355056.aspx