Исключение удаленного взаимодействия .NET

StackOverflow https://stackoverflow.com/questions/73825

  •  09-06-2019
  •  | 
  •  

Вопрос

Речь идет о том, когда генерируется исключение удаленного взаимодействия .NET.Если вы взглянете на MSDN, там будет упомянуто, что исключение удаленного взаимодействия генерируется, когда что-то идет не так с удаленным взаимодействием.Если мой сервер не запущен, я получаю исключение сокета, и это нормально.

То, что я пытаюсь выяснить, это:точно ли получение исключения удаленного взаимодействия указывает на то, что мой сервер запущен?Если да, то это решило бы проблему.Если нет:Есть ли способ выяснить, возникло ли исключение удаленного взаимодействия на стороне клиента или на стороне сервера?

Обновить:

Проблема, которую я пытаюсь решить, заключается в том, что сервер изначально не работает, а затем клиент отправляет на сервер какое-то сообщение.Теперь я получаю исключение сокета, в котором говорится "Не удалось установить соединение ...", и это нормально.

Существует поток, который регулярно отправляет сообщения на сервер, чтобы проверить, доступен ли сервер.Теперь появляется сервер, и в этот момент вы можете получить ответ, который в порядке, или вы можете получить какое-то исключение, и, скорее всего, это будет удаленное исключение.Итак, я пытаюсь спросить следующее:в случае, если я не получаю сообщение и получаю удаленное исключение, есть ли вероятность, что сервер запущен, и я все еще получаю это исключение?

Все, что я делаю, это просто вызываю метод для удаленного объекта, который ничего не делает и возвращает.Если нет исключения, значит, у меня все хорошо.Теперь, если есть исключение удаленного взаимодействия, и если я знал, что исключение удаленного взаимодействия произошло на сервере, то я знаю, что, несмотря на получение исключения, я подключен к серверу.

Это было полезно?

Решение

Получение исключения удаленного взаимодействия не гарантирует, что ваш сервер запущен.Если что-то еще запущено и прослушивается на этом порту, соединение будет успешным, и вы не получите исключение сокета.То, что происходит в этом случае, зависит от того, как ведет себя приложение, которое на самом деле получило ваше соединение, но это, вероятно, приведет к генерации исключения удаленного взаимодействия в вашем клиенте.

Потребовалось бы немного больше исследований, чтобы проверить это, но я полагаю, что исключение удаленного взаимодействия указывает на проблему в обмене данными между клиентом и сервером, поэтому не существует "клиентской стороны" или "серверной стороны", которые его сгенерировали.Это означает, что эти двое разговаривали невесело, и это могло быть вызвано любым из них.

Другие советы

Если вы собираетесь использовать пользовательские типы исключений, которые будут передаваться через область удаленного взаимодействия, обязательно пометьте эти типы как "[Serializable]".Я не могу вспомнить точное сообщение об ошибке, но оно озадачивало меня большую часть дня, когда я впервые увидел его.

Кроме того, просто подсказка, TargetInvocationException часто имеет РЕАЛЬНОЕ исключение, встроенное в его свойство InnerException.Нет ничего более бесполезного, чем "Исключение было сгенерировано целью вызова".

Попробуйте убедиться, что вы отправляете правильное сообщение и сообщения, полученные сервером, также верны, напримериспользование утверждений (это называется проектированием по контракту).Если у вас есть такая возможность, попробуйте отладить серверную и клиентскую части одновременно.(запуск двух экземпляров VS одновременно)

У меня нет доступа к исходному коду моего последнего приложения удаленного взаимодействия, но, насколько я помню, мы не смогли найти способ точно узнать, был ли сервер запущен из-за какого-либо из полученных нами исключений.
Мы проверили, присутствует ли сеть, и предупредили пользователя, если нет (я думаю, это метод в классе Environment).

Если логика приложения на стороне сервера выдала исключение, оно должно иметь возможность передать его клиенту, чтобы сообщить ему, что произошло.Вы можете проверить это, намеренно создав исключение в одном из методов удаленного объекта.Затем вызовите этот конкретный метод со стороны клиента, ожидая исключения:

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-порту, вы получите исключение SocketException.В конце концов, сервер не прослушивает и не отвечает на этот порт, как клиент вообще может установить соединение с сокетом?

Но, если вы получаете 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