2009-09-25 5 views
5

У меня есть приложение, имеющее доступ к .NET API. Их библиотека API взаимодействует со своим основным приложением через удаленные удаленные вызовы .NET. Чтобы использовать API, приложение должно быть запущено и запущено.Как узнать, зарегистрировано ли в другом приложении канал IPC Remoting?

Итак, у меня есть экземпляр, где мне нужно программно запустить приложение, а затем создать экземпляр одного из объектов API, который пытается открыть канал удаленного доступа IPC к основному приложению. Проблема в том, что после запуска процесса есть несколько секунд между запуском и когда приложение регистрирует канал. Если я попытаюсь создать экземпляр объекта API до того, как канал зарегистрирован, он будет биться.

Это не помогает, я очень мало знаю о удалении .NET.

Как определить из приложения MY, которое использует их API, если приложение ИРИ зарегистрировало канал для связи, поэтому я знаю, что это нормально, чтобы создать экземпляр своего объекта API?

+0

Jon Skeet! Вы должны знать ответ! = [ – snicker

ответ

2

Попробуйте это:

using System.Net.NetworkInformation; 
using System.Net; 
private static bool IsPortAvailable(int port) 
{ 
     IPGlobalProperties globalProperties = IPGlobalProperties.GetIPGlobalProperties(); 
     IPEndPoint[] activeListeners = globalProperties.GetActiveTcpListeners(); 
     if (activeListeners.Any(conn => conn.Port == port)) 
     { 
      return true; 
     } 
     return false; 
} 

Pass в порту, и вы должны получить значение, указывающее, есть ли слушатель на этом port.Hope это помогает

+1

Проблема в том, что это не порт. Это IPC удаленно, поэтому есть «имена» портов, но не фактические порты. – snicker

+0

Если вы программно создаете процесс, который прослушивает подключения, он должен прослушиваться на каком-то порту. В этом примере MSDN есть сервер, который прослушивает вызовы IPC на порту 9090: http://msdn.microsoft.com/en-us/library/system.runtime.remoting.channels.ipc.ipcchannel.aspx Если вы не наняли, t знать порт, попробуйте запустить netstat из строки commannd, вы должны уметь видеть, какие порты используются –

+0

А, это, кажется, имеет смысл. Однако порт меняется случайным образом. Любые предложения для этого? – snicker

0

Просто выйти из коробки для момент, вы подумали об использовании WCF с MSMQ? Я не уверен, что я полностью понимаю, что вы архитектура, но похоже, что клиент API должен развернуть еще один процесс, на котором размещен API. При запуске хоста API может возникнуть проблема синхронизации, и когда клиент пытается совершать вызовы. Недавно Microsoft отвергла .NET Remoting (а также все другие предыдущие технологии связи, такие как веб-службы ASMX) как устаревшие, и настоятельно рекомендует разработчикам перейти на платформу WCF.

Если вы используете WCF с MSMQ, у вас не должно быть проблем с синхронизацией. Ваше клиентское приложение может отбрасывать сообщения в надежной очереди независимо от того, запущен ли хост API или нет. Хост API может быть запущен в любое время, и он будет обрабатывать и обрабатывать любые сообщения, ожидающие очереди. Даже если у вас все еще есть клиентское приложение, запускающее хост API, проблема синхронизации больше не будет проблемой, потому что вы используете очередь для передачи сообщений, а не .NET Remoting. WCF обеспечивает приятную, удобную и удобную оболочку вокруг MSMQ, поэтому барьер для входа относительно невелик.

Другая красивая вещь об использовании WCF поверх .NET Remoting заключается в том, что вы можете легко перемещать хост API на другой физический сервер без необходимости изменять клиентские приложения. Вы могли бы даже перейти на другую платформу очередей, если захотите (например, RabbitMQ на AMQP), не изменяя ни клиентские, ни клиентские приложения API. WCF обрабатывает все это взаимодействие для вас, обеспечивая более чистую развязку и более надежную связь между вашим клиентским приложением и хостом API.

Если переход к WCF не является вариантом, вы должны иметь возможность явно устанавливать порт с помощью .NET Remoting. Я не знаю, как вы настраиваете API хоста, но URL для любого данного хуторе объекта, как правило, в виде:

tcp://<hostname>[:<port>]/<object> 

Если добавить порт, то вы должны быть в состоянии использовать решение Abhijeet для определить, открыт ли порт или нет. Вы не будете получать свободные связи и надежные коммуникационные преимущества WCF, но это определенно будет меньше. ;)

+0

WCF - это не вариант. Я не контролирую источник сервера. Существует закрытое исходное приложение, написанное на неуправляемом языке (вероятно, C++) и API, предоставляемом в виде библиотеки .NET. Библиотека - это то, что создает удаленные объекты. Я должен использовать удаленный доступ, хотя я знаю, что он устарел и сосет. – snicker

0

Рассматривали ли вы попытку создать экземпляр объекта API в блок try-catch? Затем вы можете проанализировать исключение и посмотреть, вызвано ли это тем, что сервер не прослушивает. И если бы это было так, вы можете просто подождать и повторить попытку.

Имеет смысл?

+0

Да, но, к сожалению, закрытый API-интерфейс написан плохо, и он устанавливает некоторые статические переменные, которые препятствуют тому, чтобы он был снова создан в той же среде исполнения, не используя тонны отражения, чтобы исправить это. Это было бы противное решение. – snicker

+0

Сделайте это в другом AppDomain? –

+0

Я попытался обернуть myObj = Activator.GetObject (...) в блоке try-catch, тестировать нуль и т. Д. Это не сработает, потому что он возвращает объект _TransparentProxy, независимо от того, вверх или нет сервер. Это не позже, когда вы пытаетесь использовать myObj, который вы наклоняете. На мой взгляд, Abjiheet имеет правильный ответ. – IAbstract

0

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

using System.Net.NetworkInformation; 
using System.Net; 
private static bool IsPortAvailable(int port) 
{ 
    IPGlobalProperties globalProperties = IPGlobalProperties.GetIPGlobalProperties(); 
    IPEndPoint[] activeListeners = globalProperties.GetActiveTcpListeners(); 
    if (activeListeners.Any(conn => conn.Port == port)) 
    { 
     return true; 
    } 
    return false; 
} 
0

При регистрации IpcServerChannel это именованный канал для связи через с именем имя порта, который вы выбрали для вашего IpcServerChannel. Вы можете посмотреть список Именованных каналов, чтобы узнать, есть ли ваше имя порта.

System.IO.Directory.GetFiles(@"\\.\pipe\").Any((path) => path.Contains(@"\\.\pipe\" + pipeName)); 
Смежные вопросы