سؤال

يتعلق الأمر بالوقت الذي يتم فيه طرح استثناء الاتصال عن بعد لـ .NET.إذا ألقيت نظرة على MSDN، فسوف يذكر أنه يتم طرح استثناء الاتصال عن بعد عندما يحدث خطأ ما أثناء الاتصال عن بعد.إذا كان الخادم الخاص بي لا يعمل، أحصل على استثناء مأخذ توصيل وهو أمر جيد.

ما أحاول معرفته هو:هل الحصول على استثناء للعمل عن بعد يشير بالتأكيد إلى أن الخادم الخاص بي جاهز للعمل؟إذا كانت الإجابة بنعم، فهذا من شأنه أن يحل المشكلة.ان لم:هل هناك طريقة لمعرفة ما إذا كان الاستثناء عن بعد قد نشأ من جانب العميل أم من جانب الخادم؟

تحديث:

المشكلة التي أحاول حلها هي أن الخادم معطل في البداية ثم يرسل العميل بعض الرسائل إلى الخادم.الآن أحصل على استثناء مأخذ توصيل يقول "لا يمكن إجراء اتصال..." وهذا أمر جيد.

يوجد مؤشر ترابط يرسل رسائل إلى الخادم على فترات زمنية منتظمة لمعرفة ما إذا كان الخادم متاحًا.الآن، يأتي الخادم، وعند هذه النقطة، يمكنك الحصول على الاستجابة التي لا بأس بها أو يمكنك الحصول على بعض الاستثناءات وعلى الأرجح سيكون استثناءً بعيدًا.لذا، ما أحاول أن أسأله هو:في حالة عدم تلقي رسالة وحصلت على استثناء عن بعد، هل هناك احتمال أن يكون الخادم قيد التشغيل وما زلت أتلقى هذا الاستثناء؟

كل ما أفعله هو مجرد استدعاء طريقة على الكائن البعيد لا تفعل شيئًا وتعود.إذا لم يكن هناك استثناء فأنا بخير.الآن، إذا كان هناك استثناء للعمل عن بعد وإذا كنت أعرف أن الاستثناء عن بعد قد حدث على الخادم، فأنا أعلم أنه على الرغم من حصولي على الاستثناء، فأنا متصل بالخادم.

هل كانت مفيدة؟

المحلول

الحصول على استثناء عن بعد لا يضمن أن الخادم الخاص بك جاهز للعمل.إذا حدث شيء آخر قيد التشغيل والاستماع على هذا المنفذ، فسينجح الاتصال، ولن تحصل على استثناء مأخذ التوصيل.ما يحدث في هذه الحالة يعتمد على كيفية عمل التطبيق الذي حصل على اتصالك بالفعل، ولكن من المحتمل أن يؤدي ذلك إلى إنشاء استثناء عن بعد في العميل الخاص بك.

قد يستغرق الأمر مزيدًا من التحقيق للتحقق من ذلك، لكنني أعتقد أن الاستثناء عن بعد يشير إلى مشكلة في الاتصالات بين العميل والخادم، لذلك لا يوجد "جانب العميل" أو "جانب الخادم" الذي أنشأه.هذا يعني أن الاثنين لم يكونا يتحدثان بسعادة وقد يكون السبب هو أحدهما.

نصائح أخرى

إذا كنت تنوي استخدام أنواع الاستثناءات المخصصة ليتم طرحها عبر حدود التحكم عن بعد، فتأكد من وضع علامة على هذه الأنواع بأنها "[قابلة للتسلسل]".لا أستطيع أن أتذكر رسالة الخطأ بالضبط، لكنها حيرتني طوال الجزء الأكبر من اليوم عندما رأيتها لأول مرة.

أيضًا، مجرد نصيحة، غالبًا ما يحتوي TargetInvocationException على الاستثناء الحقيقي المضمن في خاصية InnerException الخاصة به.لا يوجد شيء عديم الفائدة أكثر من "تم طرح استثناء بواسطة هدف الاحتجاج".

حاول التأكد من أنك أرسلت الرسالة الصحيحة وأن الرسائل التي يتلقاها الخادم صحيحة أيضًا، على سبيل المثال.باستخدام التأكيدات (ويسمى التصميم بالعقد).إذا كان لديك مثل هذا الاحتمال، فحاول تصحيح الأخطاء من جانب الخادم والعميل في نفس الوقت.(تشغيل مثيلين VS في نفس الوقت)

لم أتمكن من الوصول إلى الكود المصدري لتطبيق الاتصال عن بعد الأخير الخاص بي، ولكن بقدر ما أستطيع أن أتذكر لم نتمكن من اكتشاف طريقة لمعرفة ما إذا كان الخادم قد تم تشغيله من أي من الاستثناءات التي حصلنا عليها.
لقد تحققنا لمعرفة ما إذا كانت الشبكة موجودة وحذرنا المستخدم إذا لم تكن موجودة (طريقة في فئة البيئة على ما أعتقد).

إذا طرح منطق التطبيق من جانب الخادم استثناءً، فيجب أن يكون قادرًا على التنظيم إلى العميل لإعلامه بما حدث.يمكنك اختبار ذلك عن طريق طرح استثناء عمدًا في إحدى أساليب الكائن البعيد.ثم اتصل بهذه الطريقة المحددة من جانب العميل متوقعًا حدوث استثناء:

HttpChannel channel = new HttpChannel();
ChannelServices.RegisterChannel(channel);

IMyRemoteObject obj = (IMyRemoteObject) Activator.GetObject(
    typeof(IMyRemoteObject),
    "http://localhost:1234/MyRemoteObject.soap");
Console.WriteLine("Client.Main(): Reference to rem.obj. acquired");
    int tmp = obj.GetValue();
    Console.WriteLine("Client.Main(): Original server side value: {0}",tmp);
Console.WriteLine("Client.Main(): Will set value to 42");

try
{
    // This method will throw an ApplicationException in the server-side code.
    obj.SetValue(42);
}
catch (Exception ex)
{
    Console.WriteLine("=====");
    Console.WriteLine("Exception type: " + ex.GetType().ToString());
    Console.WriteLine("Message: " + ex.Message);
    Console.WriteLine("Source: " + ex.Source);
    Console.WriteLine("Stack trace: " + ex.StackTrace);
    Console.WriteLine("=====");
}

يمكنك توقع تلقي استثناء مثل هذا

=====
Exception type: System.ApplicationException
Message: testing
Source: Server
Stack trace:
Server stack trace:
   at Server.MyRemoteObject.SetValue(Int32 newval) in i:\projects\remoting.net\ch03\01_singlecallobjects\server\server.cs:line 27
   at System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(MethodBase mb, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
   at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)

Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at General.IMyRemoteObject.SetValue(Int32 newval)
   at Client.Client.Main(String[] args) in i:\projects\remoting.net\ch03\01_singlecallobjects\client\client.cs:line 29
=====

يجب أن يخبرك أن المصدر موجود على الخادم، مع تتبع المكدس من جانب الخادم.

حسنًا، بعد أن وضعت الأمر على هذا النحو، أفترض أنك تستخدم TCP للاتصال عن بُعد، لأنه إذا كان ذلك عبر HTTP، فسيتم طرح WebException عند الفشل في الاتصال بخادم (منفذ شبكة TCP).عندما لا يقوم الخادم بتشغيل برنامج التطبيق لتسجيل القناة على منفذ TCP المعين، سوف تحصل على JackException.بعد كل شيء، الخادم لا يستمع/يستجيب لهذا المنفذ، كيف يمكن للعميل إجراء اتصال بمأخذ توصيل؟

ولكن، إذا حصلت على RemotingException، فستحتاج إلى ذلك لا يعني بالضرورة أن الخادم لديه تطبيق الاتصال عن بعد المناسب الذي يعمل بشكل جيد.يمكنك الاختبار عن طريق الاتصال بمعرف URI خاطئ على منفذ خاطئ، مثل المنفذ 80 (IIS).

IMyRemoteObject obj = (IMyRemoteObject) Activator.GetObject(
    typeof(IMyRemoteObject),
    "tcp://localhost:80/MyRemoteObject.rem");

قد يؤدي ذلك إلى RemotingException لأنه بينما يمكن للعميل إجراء اتصال TCP بالمنفذ 80، فإن IIS يستجيب للمكالمة وليس تطبيق الاتصال عن بعد؛لا يمكن لـ IIS التعامل مع مكالمات الاتصال عن بعد مباشرةً.بعد قولي هذا، يمكن أن يعني RemotingException أيضًا وجود مشكلة من جانب العميل.قد تساعدك مقالة المدونة هذه على فهم أفضل.

http://www.cookcomputing.com/blog/archives/000308.html

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top