2010-05-12 16 views
7

हमें .NET Remoting के साथ एक अजीब समस्या है। असल में, हम एक सर्वर जो ChannelServices.RegisterChannel() के साथ दो TcpChannels पंजीकृत करता है:.NET Remoting स्विचिंग चैनल स्वयं ही

  1. एक बंदरगाह पर सुनता 50000
  2. अन्य एक बंदरगाह पर सुनता है 15000.

हम तो एक ग्राहक है कि करने के लिए एक TcpChannel पंजीकृत करता है सर्वर के साथ संवाद करने में सक्षम हो। हम यूआरआई

साथ Activator.GetObject() फोन करके सर्वर से एक एक वस्तु प्राप्त करें "टीसीपी: // serverip: 50000/objectname"

और इस ठीक काम करता है, ग्राहक बंदरगाह पर सर्वर से कनेक्ट 50000 और वस्तु प्राप्त करता है।

हालांकि, जब हम उस ऑब्जेक्ट पर कॉलिंग विधियों को प्रारंभ करना शुरू करते हैं, तो पोर्ट 50000 पर चैनल से कनेक्शन गिरा दिया जाता है, और चैनल 15000 पर स्वचालित रूप से चैनल के साथ एक नया कनेक्शन बनाया जाता है। यह हमारे लिए एक वास्तविक समस्या है क्योंकि हम पोर्ट 15000 पर यातायात नहीं चाहते हैं क्योंकि वह चैनल सर्वर पर बंदरगाह 50000 चैनल के रूप में एक ही नेटवर्क एडेप्टर से बंधे नहीं हो सकता है या वह पोर्ट फ़ायरवॉल में खुला नहीं हो सकता है, जिसके कारण स्वाभाविक रूप से विफल होने के लिए रिमोटिंग कॉल।

यह हमारे लिए बहुत अजीब है क्योंकि ग्राहक को हमारे कोड में कोई ज्ञान नहीं है कि पोर्ट 15000 पर सर्वर पर एक और चैनल मौजूद है या यह किस आईपी को सुनता है, फिर भी यह उससे जुड़ने का प्रयास करता है।

IDictionary props = new Hashtable(); 

props["port"] = m_tcpPort; 
props["name"] = String.Empty; 


BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); 
serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; 

BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider(); 

m_tcpChannel = new TcpServerChannel(props, /*clientProvider,*/ serverProvider); 
ChannelServices.RegisterChannel(m_tcpChannel, false); 

m_wellKnownObjRef = RemotingServices.Marshal(this, "[email protected]" + m_tcpPort.ToString()); 
:

इस पर कोई मदद बहुत सराहना की है,

धन्यवाद, कैस्पर

इस कोड है कि सर्वर चैनलों में से एक है, आमतौर पर पोर्ट 50000 पर एक सेट करता है

यह वह कोड है जो अन्य सर्वर चैनल सेट करता है, आमतौर पर पोर्ट 15000:

IDictionary props = new Hashtable(); 

props["name"] = String.Empty; 
props["port"] = ip.Port; 
props["bindTo"] = ip.Address.ToString();      
props["timeout"] = REMOTING_TIMEOUT; // Timeout to prevent hung remoting calls. 

if (!String.IsNullOrEmpty(machineName)) 
{ 
    props["machineName"] = machineName; 
} 

    BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); 
    serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; 

    BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider(); 

    m_channel = new TcpChannel(props, clientProvider, serverProvider); 
    ChannelServices.RegisterChannel(m_channel, false); 

    m_objRef = RemotingServices.Marshal(this, QueueName); // Queuename is a GUID. 

इस ग्राहक पहली बार सर्वर चैनल से कनेक्ट होता है में कोड, एक बंदरगाह 50000 पर आमतौर पर है कि है:

IDictionary props = new Hashtable(); 

props["port"] = 0; 

RemotingConfiguration.CustomErrorsMode = CustomErrorsModes.Off; 

BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); 
serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; 

BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider(); 

m_tcpChannel = new TcpClientChannel(props, clientProvider/*, serverProvider*/); 
ChannelServices.RegisterChannel(m_tcpChannel, false); 

string address = "tcp://" + profile.RemoteIP + ":" + profile.RemoteTCP; 

m_server = (Kernel)Activator.GetObject(typeof(Server), address + "/[email protected]" + port); 
+0

यदि आपके पास app.config फ़ाइल में कोई चैनल कॉन्फ़िगरेशन है तो इसे अपने प्रश्न में जोड़ें। –

+0

उत्तर देने के लिए धन्यवाद। कोई app.config कॉन्फ़िगरेशन नहीं है क्योंकि यह कोड में सभी सेटअप है। मैंने उस कोड को अब प्रश्न में जोड़ा है। – Casper

उत्तर

7

हमने माइक्रोसॉफ्ट के साथ इस बारे में एक समर्थन केस लॉग किया है और स्पष्ट रूप से, हम यहां क्या कर रहे हैं .NET Remoting द्वारा समर्थित नहीं है। आपको केवल एक ऐपडोमेन में प्रत्येक प्रकार के एक चैनल को पंजीकृत करने की अनुमति है। क्या रिमोटिंग यह है कि यह क्लाइंट को ऑब्जेक्ट के यूआरआई को यह बताने के लिए भेजता है कि यह कहां से ऑब्जेक्ट तक पहुंच सकता है। जब ऐसा होता है तो यह सर्वर के अंत में पंजीकृत चैनलों को देखता है और पहले चैनल का उपयोग करता है जो उसे वहां मिलता है जो अनुरोध किए गए प्रकार से मेल खाता है (हमारे मामले में: टीसीपी)। दूसरे शब्दों में यह पहले से पंजीकृत होने के लिए जो भी चैनल होता है उसका उपयोग करेगा। यह इस बात पर परवाह नहीं करता कि क्लाइंट ने किस चैनल पर कनेक्ट किया है।

समाधान क्लाइंट पक्ष पर अपना स्वयं का ICLientChannelSinkProvider लागू करना है। जब आप CreateSink() विधि को कार्यान्वित करते हैं तो आप यह चुन सकते हैं कि आप किस यूआरएल को क्लाइंट से कनेक्ट करना चाहते हैं जब आप सिंक बनाने के लिए कनेक्ट करते हैं।

+0

स्पष्टीकरण के लिए धन्यवाद! हम काफी समय से खोज रहे हैं कि कई एनआईसी के लिए चैनल बनाते समय हमारा सर्वर हमेशा सही तरीके से प्रतिक्रिया क्यों नहीं दे रहा था। आपके द्वारा वर्णित कारण और समाधान थे। – Philippe

0

मैं उन के साथ stuggle था बंदरगाहों के रूप में अच्छी तरह से "backlinked"; मैंने सोचा कि यह केवल तभी होगा जब सर्वर कुछ वापस भेजना चाहता है (यहां तक ​​कि एक घटना-प्रक्रिया में)। क्योंकि मुझे हमेशा फ़ायरवॉल के साथ समस्याएं थीं, इसलिए मैंने जेन्यूइन चैनल्स पर स्विच किया (हालांकि मुझे लगता है कि यह थोड़ा पुराना है)।

+0

खुद को रिमोट करना अब पुराना है, डब्लूसीएफ द्वारा प्रतिस्थापित किया गया है। –

+0

वास्तव में यह है। जिस कोड में हमें समस्याएं आ रही हैं उन्हें वापस लिखा गया था जब .NET Framework 1.0 अभी बाहर आया था। ऐसा लगता है कि इन सभी वर्षों में किसी ने भी इस समस्या को ध्यान में नहीं देखा है जब तक कि हमारे ग्राहकों में से एक ने अलग-अलग नेटवर्क एडेप्टरों को दो चैनलों को बांधने की कोशिश नहीं की। – Casper

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