title: separating out a wcf service, server, and client
body: <p>I have a solution in VS 2010: a WCF Service Library project ("NotifyService") and two Windows Forms projects, one for a server ("NotifyServer")and one for a client ("NotifyClient"). My goal is to have a duplex WCF service that will notify any number of connected clients when the server pushes out a notification. The clients do not need to communicate to the server except to subscribe and unsubscribe from the server's updates. However I seem to be running into problems nailing down the InstanceContext.</p>
  
  <p>Here's the code for the WCF service:</p>
  
  <pre><code>&lt;ServiceContract(
      CallbackContract:=GetType(INotifyCallback),
      SessionMode:=SessionMode.Required)&gt;
  Public Interface INotifyService
      &lt;OperationContract()&gt;
      Sub Notify(ByVal what As String)
  
      &lt;OperationContract()&gt;
      Sub Subscribe()
  
      &lt;OperationContract()&gt;
      Sub Unsubscribe()
  
  End Interface
  
  Public Interface INotifyCallback
      &lt;OperationContract(IsOneWay:=True)&gt;
      Sub OnNotify(ByVal what As String)
  End Interface
  
  &lt;ServiceBehavior(
      ConcurrencyMode:=ConcurrencyMode.Single,
      InstanceContextMode:=InstanceContextMode.PerCall)&gt;
  Public Class NotifyService
      Implements INotifyService
  
      Private _callbacks As New List(Of INotifyCallback)
  
      Public Sub Notify(ByVal what As String) Implements INotifyService.Notify
          For Each callback As INotifyCallback In _callbacks
              callback.OnNotify(what)
          Next
      End Sub
  
      Public Sub Subscribe() Implements INotifyService.Subscribe
          Dim client As INotifyCallback = OperationContext.Current.GetCallbackChannel(Of INotifyCallback)()
          If Not _callbacks.Contains(client) Then
              _callbacks.Add(client)
          End If
      End Sub
  
      Public Sub Unsubscribe() Implements INotifyService.Unsubscribe
          Dim client As INotifyCallback = OperationContext.Current.GetCallbackChannel(Of INotifyCallback)()
          If _callbacks.Contains(client) Then
              _callbacks.Remove(client)
          End If
      End Sub
  End Class
  </code></pre>
  
  <p>The Server form has a reference to the DLL created by the service library and self-hosts an instance of the WCF server in code:</p>
  
  <pre><code>Public Class frmServer
      Private _host As ServiceHost
      Private _notifier As NotifyService.NotifyService
  
      Public Sub go() Handles Me.Load
          _host = New ServiceHost(GetType(NotifyService.NotifyService), New Uri("net.tcp://localhost:10000"))
          _host.AddServiceEndpoint(GetType(NotifyService.INotifyService), New NetTcpBinding, "NotifyService")
          _host.Description.Behaviors.Add(New ServiceMetadataBehavior)
          _host.AddServiceEndpoint(GetType(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding, "mex")
          _host.Open()
          _notifier = New NotifyService.NotifyService
      End Sub
  
      Private Sub send() Handles Button1.Click
          _notifier.Notify("Foo")
      End Sub
  End Class
  </code></pre>
  
  <p>For the most part that all seems to work. I can use the WcfTestClient to connect and it at least sees the services, though since it's a net.tcp binding with duplex enabled I can't actually test it using that client.</p>
  
  <p>When I created the client I added a service reference called NotifyGateway. Here's the client form code:</p>
  
  <pre><code>&lt;CallbackBehavior(
      ConcurrencyMode:=ConcurrencyMode.Single,
      UseSynchronizationContext:=False)&gt;
  Public Class frmClient
      Implements NotifyGateway.INotifyServiceCallback
  
      Private _service As NotifyGateway.NotifyServiceClient = Nothing
  
      Public Sub OnNotify(ByVal what As String) Implements NotifyGateway.INotifyServiceCallback.OnNotify
          MsgBox(what)
      End Sub
  
      Public Sub go() Handles Button1.Click
          _service = New NotifyGateway.NotifyServiceClient(New InstanceContext(Me), New NetTcpBinding, New EndpointAddress("net.tcp://localhost:10000/NotifyService"))
          _service.Open()
          _service.Subscribe()
      End Sub
  End Class
  </code></pre>
  
  <p>Since I'm setting everything up through code, there are no app.config files. The problem I'm having is that my Subscribe method is never called. When debugging, I get an error after stepping through that line (not an exception) that says "Unable to automatically step into the server. The debugger failed to stop in the server process." When I go back to my server form and click the button designed to raise an event on the callback clients, it steps into the NotifyService class but the <code>_callbacks</code> list is empty, meaning the Subscribe method either never ran, or it never ran on that instance.</p>
  
  <p>I have fought with this for almost a week. This is nearly an identical copy, at least on the service-side, to what was described <a href="http://www.codeproject.com/KB/WCF/WCF_Duplex_UI_Threads.aspx" rel="nofollow">here</a>, and I've compiled that and it works. So I'm a little lost as to where I'm going wrong...</p>