Handling WCF events in another process

被刻印的时光 ゝ 提交于 2019-12-07 08:02:39

问题


I have a non-serializable object that I would like to access from a separate process. I've looked around and it seems the only viable option is to use WCF but I'm not sure how to do this as I'm new to WCF. If I create a WCF service, how do I 'hook' the WinForm into the various events in the WCF service? For example, the user communicates with the WCF service directly and I would likemy WinForm client to be notified. How would I be able to know when the user has done something with the WCF service and have the WinForm client pick up on that?


回答1:


A way to achieve what you are looking for is to implement a callback contract on your service. Then your win-forms app would be able to "subscribe" to events fired on the service (such as modifications to your object).

To do this you implement a service contract with a callback contract:

[ServiceContract]
public interface IMyService_Callback
{
    [OperationContract(IsOneWay = true)]
    void NotifyClients(string message);
}

[ServiceContract(CallbackContract = typeof(IMyService_Callback))]
public interface IMyService
{
    [OperationContract]
    bool Subscribe();
}

You then implement your service:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class MyService : IMyService
{
    private List<IMyService_Callback> callbacks;

    public MyService()
    {
        this.callbacks = new List<IMyService_Callback>();
    }

    private void CallClients(string message)
    {
        callbacks.ForEach(callback => callback.NotifyClients(message));
    }

    public bool Subscribe()
    {
        var callback = OperationContext.Current.GetCallbackChannel<IMyService_Callback>();

        if (!this.callbacks.Contains(callback))
        {
            this.callbacks.Add(callback);
        }

        // send a message back to the client
        CallClients("Added a new callback");

        return true;
    }
}

In your winforms client you only need to implement the callback method:

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, UseSynchronizationContext = false)]
public partial class ServiceClient : Form, IMyService_Callback
{
    // Sync context for enabling callbacks
    SynchronizationContext uiSyncContext;

    public ServiceClient()
    {
        InitializeComponent(); //etc.

        uiSyncContext = SynchronizationContext.Current;

        // Create proxy and subscribe to receive callbacks
        var factory = new DuplexChannelFactory<IMyService>(typeof(ServiceClient), "NetTcpBinding_IMyService");
        var proxy = factory.CreateChannel(new InstanceContext(this));
        proxy.Subscribe();
    }

    // Implement callback method
    public void NotifyClients(string message)
    {
        // Tell form thread to update the message text field
        SendOrPostCallback callback = state => this.Log(message);

        uiSyncContext.Post(callback, "Callback");
    }

    // Just updates a form text field
    public void Log(string message)
    {
        this.txtLog.Text += Environment.NewLine + message;
    }
}    

Config for service:

<system.serviceModel>
  <services>
    <service name="TestService.MyService" behaviorConfiguration="Normal">
      <endpoint 
        address="net.tcp://localhost:8000/MyService" 
        contract="TestService.IMyService" 
        binding="netTcpBinding" />
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="Normal" >
        <serviceDebug includeExceptionDetailInFaults="true"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

Config for client

<system.serviceModel>
  <client>
    <endpoint address="net.tcp://localhost:8000/MyService" 
              binding="netTcpBinding"
              contract="TestService.IMyService"
              name="NetTcpBinding_IMyService">
    </endpoint>
  </client>
</system.serviceModel>


来源:https://stackoverflow.com/questions/8889051/handling-wcf-events-in-another-process

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!