Исключение .NET Remoting - PullRequest
       15

Исключение .NET Remoting

5 голосов
/ 16 сентября 2008

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

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

Обновление:

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

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

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

Ответы [ 6 ]

2 голосов
/ 16 сентября 2008

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

Кроме того, TargetInvocationException - всего лишь подсказка. Зачастую в его свойство InnerException встроено исключение REAL. Нет ничего более бесполезного, чем «Исключение было сгенерировано целью вызова».

1 голос
/ 16 сентября 2008

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

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

0 голосов
/ 16 сентября 2008

Хорошо, теперь, когда вы сформулировали это так, я предполагаю, что вы используете TCP для удаленного взаимодействия, поскольку, если бы он был через HTTP, это было бы WebException, возникающее при неудачном соединении с сервером (сетевой порт TCP). Когда сервер не запустил прикладную программу для регистрации канала на указанном порте TCP, вы получите исключение SocketException. В конце концов, сервер не прослушивает / не отвечает на этот порт, как клиент может установить соединение через сокет?

Но, если вы получаете RemotingException, необходимо, чтобы не обязательно означало, что на сервере правильно работает приложение Remoting. Вы можете проверить, подключившись к неправильному URI на неправильном порту, например, к порту 80 (IIS).

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

Это может привести к исключению RemotingException, поскольку, хотя клиент может установить TCP-соединение с портом 80, на вызов отвечает IIS, а не приложение Remoting; IIS не может обрабатывать удаленные вызовы напрямую. Сказав это, RemotingException также может означать проблему на стороне клиента. Эта статья блога может помочь вам лучше понять.

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

0 голосов
/ 16 сентября 2008

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

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
=====

В нем должно быть указано, что источник находится на сервере с трассировкой стека на стороне сервера.

0 голосов
/ 16 сентября 2008

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

0 голосов
/ 16 сентября 2008

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

...