简体   繁体   English

WPF与托管WCF服务之间的通信

[英]Communication between WPF and hosted WCF Service

I have a console app that starts a WCF service and a small WPF app. 我有一个启动WCF服务的控制台应用程序和一个小型WPF应用程序。 I'm trying to show a messagebox in the WPF app whenever a method on the WCF service is called for testing purposes. 每当试图出于测试目的而调用WCF服务上的方法时,我都试图在WPF应用程序中显示一个消息框。 I have based my code on this answer but the synchronizationContext is null. 我已经基于答案编写了代码,但笔者的conferenceContext为空。 How do i fix this? 我该如何解决? Or are there other/better ways to make this happen? 还是有其他/更好的方法来实现这一目标?

Use SignalR . 使用SignalR Lots of info here and here . 在这里这里有很多信息。 This article also looks very good. 这篇文章看起来也很好。

As for actual code, create a WCF service and use NuGet to add a reference to SignalR, then add a hub class: 对于实际代码,创建WCF服务并使用NuGet添加对SignalR的引用,然后添加中心类:

public class ServiceMonitorHub : Hub
{
}

You'll also need to add an Owin startup class to start the SignalR hub: 您还需要添加一个Owin启动类来启动SignalR集线器:

[assembly: OwinStartup(typeof(YourNamespace.SignalRStartup))]
namespace YourNamespace
{
    public class SignalRStartup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

Your service handlers can then get a reference to this hub and send messages to all the clients that are connected to it: 然后,您的服务处理程序可以获取对此中心的引用,并将消息发送到与其连接的所有客户端:

public class Service1 : IService1
{
    public string GetData(int value)
    {
        // send msg to clients
        var hub = GlobalHost.ConnectionManager.GetHubContext<ServiceMonitorHub>();
        hub.Clients.All.BroadcastMessage();

        return string.Format("You entered: {0}", value);
    }

Your WPF client then connects to this SignalR server and hooks in handlers to receive the messages send by the service handlers, this example contains a button handler that calls the service, as well as a connection to the SignalR hub to receive the messages that bounce back: 然后,您的WPF客户端连接到此SignalR服务器,并挂接处理程序以接收服务处理程序发送的消息,此示例包含一个调用该服务的按钮处理程序,以及与SignalR集线器的连接以接收反弹的消息:

public partial class MainWindow : Window
{
    private HubConnection Connection;
    private IHubProxy HubProxy;

    public MainWindow()
    {
        InitializeComponent();
        Task.Run(ConnectAsync);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        using (var service = new ServiceReference1.Service1Client())
            service.GetData(1);
    }

    public async Task ConnectAsync()
    {
        try
        {
            this.Connection = new HubConnection("http://localhost:59082/");
            this.HubProxy = this.Connection.CreateHubProxy("ServiceMonitorHub");
            HubProxy.On("BroadcastMessage", () => MessageBox.Show("Received message!"));
            await this.Connection.Start();
        }
        catch (Exception ex)
        {
        }
    }
}

} }

Note that clients need the NuGet SignalR.Clients package (as opposed to just SignalR). 请注意,客户端需要NuGet SignalR.Clients包(而不是仅SignalR)。

There are other ways for services to call the hub clients, this link shows a few others. 服务还有其他方式调用集线器客户端, 此链接显示了其他几种方式。

Maybe you could try ClientMessageInspector, the AfterReceiveReply of it will be called every time the client receives the message. 也许您可以尝试使用ClientMessageInspector,它的AfterReceiveReply将在每次客户端收到消息时被调用。

 public class MyClientMessageInspector : IClientMessageInspector
{
          Your message box
    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
       show message in your message box
    }
    public MyClientMessageInspector ( ){

                       }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        return null;
    }
}

To register the Inspector , you need to use an endpointBehavior 要注册检查器,您需要使用endpointBehavior

  public class MyEndpointBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {

    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.ClientMessageInspectors.Add( new MyClientMessageInspector();
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {

    }

    public void Validate(ServiceEndpoint endpoint)
    {

    }
}

And then add the behavior to your client. 然后将行为添加到您的客户端。

 using (ChannelFactory<IService> ChannelFactory = new ChannelFactory<IService>("myservice"))
        {
            ChannelFactory.Endpoint.EndpointBehaviors.Add(new MyEndpointBehavior());
            IService service = ChannelFactory.CreateChannel();
          // call method


        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM