2010-10-08 4 views
2

Я пытаюсь изучить WCF, чтобы использовать его в качестве механизма IPC для системы хоста/плагина. Хост должен иметь возможность вызвать плагин, чтобы запустить/остановить его, и плагин должен вызвать сервер обратно для ведения журнала.Использование WCF и NetNamedPipeBinding для IPC

Я сделал простой тест случай, когда хост создает конечную точку net.pipe://localhost/SampleServer со следующим ServiceContract:

[ServiceContract] 
public interface IWcfServer 
{ 
    [OperationContract] 
    void Log(string message); 
} 

И плагин создает конечную точку net.pipe://localhost/SampleClient со следующим ServiceContract:

[ServiceContract] 
public interface IWcfClient 
{ 
    [OperationContract] 
    string Init(); 
} 

Ниже приведен пример того, как я настраиваю каждую конечную точку:

this.server = new ServiceHost(this); 
this.server.AddServiceEndpoint(typeof(IWcfServer), 
           new NetNamedPipeBinding(), 
           "net.pipe://localhost/SampleServer"); 
this.server.Open(); 

А вот пример того, как я делаю звонки:

ChannelFactory<IWcfClient> factory = new ChannelFactory<IWcfClient>(
          new NetNamedPipeBinding(), 
          new EndpointAddress("net.pipe://localhost/SampleClient")); 
IWcfClient client = factory.CreateChannel(); 
using ((IClientChannel)client) 
{ 
    client.Init()); 
} 

Я уже подтвердил, что хозяин может позвонить plugin.Init(), и плагин можно назвать host.Log(message) без проблем. Однако, если это произойдет следующий сценарий:

  1. Хост называет plugin.Init()
  2. Во время исполнения plugin.Init(), плагин пытается вызвать host.Log (сообщение)

Приложения замораживаются, и я получаю TimeoutException через 1 мин. У кого-нибудь есть идеи о том, что я делаю неправильно?

+2

FYI «IsOneWay» в '' void'-возвращающем 'Log()' может помочь избежать блокировки '[OperationContract (IsOneWay = true)]' - см. Http://msdn.microsoft.com/en-us/ library/system.servicemodel.operationcontractattribute.isoneway.aspx, как описано в http://dotnet-experience.blogspot.com/2012/02/inter-process-duplex-communication-with.html – ToolmakerSteve

ответ

3

Что такое InstanceContextMode хоста службы? Если это синглтон, он будет блокироваться до тех пор, пока не вернется Init(), что приведет к циклической зависимости.

+0

Это так.Я узнал, что для этого конкретного образца это сработает, если я добавлю UseSynchronizationContext = false, но для реального приложения я в конечном итоге переписал вещи для использования InstanceContextMode.PerCall. – Badaro

0

1 мин. Стандартный тайм-аут wcf.

У вас есть круглые ссылки?

Кроме того, почему у вас есть 2 контракта, когда вы звоните по адресу client.init, который слушает?

+0

Нет круговой ссылки, см. мой комментарий к Сообщение Саяй. У меня есть два контракта и две разные конечные точки, потому что между хостом и плагином существует два независимых пути обмена. Хост реализует IWcfServer и делает вызов plugin.Init, в то время как плагин реализует IWcfClient и делает вызов host.Log. – Badaro

0

Включите трассировку E2E для WCF, чтобы проверить, что именно выбрано. - http://msdn.microsoft.com/en-us/library/ms733025.aspx. Кроме того, ваши методы могут вызывать блокировку, поскольку init может потребовать, чтобы журнал и журнал могли потребовать, чтобы init был первым или что-то в этом роде.

+0

Я знаю, что нет круговой ссылки, так как текущий журнал «реализация» - это просто MessageBox.Show (сообщение). Я включу эту трассировку и посмотрю на нее завтра. – Badaro

0

«net.pipe: // localhost/SampleServer» «net.pipe: // localhost/SampleClient» У вас есть два разных URL для сервера и для Клиента. Это проблема!

+2

Нет, это не так. Это двунаправленная связь с использованием двух разных каналов, одна для сервера -> Клиент, а другая для Client -> Server. Отсюда разные конечные точки. – Badaro

Смежные вопросы