2010-11-10 13 views
6

मैंने टोमेक जांज़ुक के Pub/sub sample using HTTP polling duplex WCF channel का पालन किया है, लेकिन मैंने देखा है कि जब कोई ग्राहक ब्राउज़र बंद करके डिस्कनेक्ट करता है तो सेवा अगली कॉलबैक पर ध्यान नहीं देती है। मैं एक अपवाद या कुछ कहने की उम्मीद करता था कि एंडपॉइंट अब और नहीं था।डिकनेक्टेड डुप्लेक्स मतदान क्लाइंट का पता लगाने के लिए

क्लाइंट कहां जाने पर आप कैसे जान सकते हैं, ताकि उस ग्राहक को प्रकाशित करना बंद कर सकें?

+0

क्या कॉलबैक विधियां "वनवे" हैं? ऑपरेशन कंट्रैक्ट विशेषता पर गलत करने के लिए IsOneWay सेट करना सर्वर को टाइमआउट का पता लगाएगा? (जवाब देने पर टिप्पणी नहीं कर रहा है, क्योंकि मुझे यकीन नहीं है) –

उत्तर

3

ऐसा लगता है कि एक असंतोषजनक है, यद्यपि सरल समाधान: यदि क्लाइंट कॉलबैक का समय समाप्त हो जाता है, तो इसे दोबारा कॉल न करें। हर n सेकंड सर्वर प्रत्येक पंजीकृत ग्राहक के लिए कॉलबैक चैनल पर एक parameterless प्रणाली को बुलाती है, बस अगर ग्राहक अभी भी वहाँ है देखने के लिए -

अपने सिस्टम में मैं भी एक पुस्तिका "जाँच" कॉल क्रियान्वित किया है। मुझे आश्चर्य हो रहा है कि क्या वास्तव में यह एक अच्छा विचार था - मुझे एक नई समस्या मिली है जहां कॉलबैक टाइमआउट जारी रहता है क्योंकि मैंने क्लाइंट को डीबगर में निलंबित कर दिया है।

+0

मेरे प्रारंभिक परीक्षण में, मुद्दा यह है कि मुझे टाइमआउट नहीं मिलता है। मैं विपरीत दृष्टिकोण को छोड़कर एक दृष्टिकोण के साथ भी आपकी कोशिश कर रहा हूं। क्लाइंट सर्वर को "पिंग" करते हैं और यदि सर्वर ने निश्चित समय में उनसे नहीं सुना है, तो वे सूची से बाहर हैं, जो मैं beleive asp.net सत्र प्रबंधन के समान है। –

+0

@ राल्फ - मैं netTcp बाइंडिंग का उपयोग कर रहा था (यह एक मोटी ग्राहक था, सिल्वरलाइट नहीं)। हो सकता है कि मतदानिंग डुप्लेक्स एचटीपी बाध्यकारी समय-समय पर न हो, इस मामले में जिस समाधान का आपने वर्णन किया है वह एकमात्र विकल्प होगा। –

5

सुनिश्चित करने के लिए: असंभव

जब कोई टीसीपी कनेक्शन बंद हो जाता है (एक HTTP कॉल अंतर्निहित), सर्वर पर एक विशेष टीसीपी संदेश भेजा जाता है - FIN पैकेट। हालांकि HTTP स्टेटलेस है, अंतर्निहित टीसीपी कनेक्शन राज्यपूर्ण है और जीवित रहने के साथ, अंतर्निहित टीसीपी कनेक्शन आमतौर पर खुला रहता है। यदि ग्राहक का निपटारा किया जाता है, तो टीसीपी कनेक्शन बंद हो जाता है और आम तौर पर सर्वर को भेजा गया संदेश। लेकिन अगर यह दुर्घटनाग्रस्त हो जाता है या उसका नेटवर्क डिस्कनेक्ट हो जाता है, तो इसमें ऐसा करने का समय नहीं होगा। तो एक शब्द में, आप कभी भी सुनिश्चित नहीं हो सकते हैं। अधिक जानकारी के लिए

Here

+0

एक शब्द में, मुझे यह जवाब पसंद है। :-) –

3

इसकी हार्ड, लगभग असंभव (सीमित एसएल डुप्लेक्स क्षमताओं का कारण)। हमने अपनी सेवा में उपयोगकर्ताओं की एक सूची लागू की है, और हमने एक संपत्ति "IsDisconnected" और LastCommunicationTime जोड़ दी है, एक बार डब्ल्यूसीएफ सेवा को टाइमआउट मिल जाता है जब उपयोगकर्ता के आउटगोइंग-संदेश-क्यू में संदेश जोड़ने का प्रयास करता है, और विफल रहता है, और अपवाद फेंकता है टाइमआउट का। हम "IsDisconnecte = true" को चिह्नित करते हैं और अगली बार उस उपयोगकर्ता को संदेश भेजने का प्रयास नहीं करते हैं।

एक और थ्रेड उस पर ध्यान रखता है और यदि यह ध्यान देता है कि अंतिम कॉम्यूनिकेशनटाइम समय के मूल्य से अधिक हो गया है और IsDisconnected = true है, तो यह उपयोगकर्ता को सूची से हटा देता है, जब तक कि वही उपयोगकर्ता इस समय के भीतर फिर से कनेक्ट करने का प्रयास नहीं करता अवधि (जिसे हम अपने उपयोगकर्ता आईडी द्वारा पहचानते हैं)।

इस समस्या को संभालने के लिए हमने मैन्युअल रूप से बहुत सी चीजें की हैं क्योंकि यह डब्ल्यूसीएफ सेवा को इतना व्यस्त बना रहा था।

+0

मैंने एक बहुत ही समान पैटर्न को अपनाना समाप्त कर दिया है। –

+0

लेकिन याद रखें: यह एक और समस्या बनाता है, सर्वर अब बहुत अधिक स्मार्ट है और उपयोगकर्ताओं को बाहर निकालने के लिए हमेशा तैयार है :), उन उपयोगकर्ताओं के बारे में जो नहीं गए हैं लेकिन बहुत चुप हैं लेकिन किसी भी तरह उनके "कनेक्शन कॉल कॉल विफल हो गया है" और उनके ग्राहक का चैनल गलती में आया है, उस स्थिति में उन्हें एक बार फिर चैनल खोलना होगा जो उन्हें एक नया सत्र-आईडी देता है, और वह चैनल सर्वर के लिए नया होगा।तो सर्वर पर पंजीकरण के बाद, सर्वर को पुराने उपयोगकर्ता आइटम को सूची से हटा देना चाहिए और एक नया/या इसे नए के साथ अपडेट करना चाहिए (क्लाइंटकॉलबैक चैनल उसमें बहुत अधिक है) –

+0

जब ग्राहक के चैनल को "जब मेक- कनेक्शन अनुरोध विफल हो गया "। सर्वर तुरंत इसके बारे में नहीं जानता है। और क्लाइंट .ChannelFaulted सर्वर पर आग लगती है जब सर्वरपूलटाइम से अधिक हो जाता है। यदि आप जानते हैं कि मेरा क्या मतलब है, तो "डब्लूसीएफ सेवा का अंधेरा कदम" है। हालांकि मैं उस मामले में सर्वरपूलटाउट के बारे में निश्चित नहीं हूं, 100%, ईमानदारी से, मुझे यह यादृच्छिक समय मिला। –

1

मुझे इस समस्या का सामना करना पड़ा और एक थ्रेड बनाया जो डिस्कनेक्ट किए गए क्लाइंट को निम्न कोड से हटा देता है। यह ठीक काम करता है लेकिन डिस्कनेक्ट क्लाइंट को 10-15 मिनट के बाद क्लाइंट सूची से छोड़ देता है (जो मेरे लिए ठीक था)।

new Thread(new ThreadStart(() => 
    { 
     while (SilverlightClients != null) 
     { 
       lock (SilverlightClients) 
       { 
        SilverlightClients = SilverlightClients.Where(d => (d.Callback as IContextChannel).State != CommunicationState.Opened).ToList(); 
       } 

      Thread.Sleep(1000); 
     } 
    })) { Name = "Thread Remove Disconnected Clients" }.Start(); 
संबंधित मुद्दे