【问题标题】:Communication between WPF and hosted WCF ServiceWPF 和托管 WCF 服务之间的通信
【发布时间】:2019-01-17 07:36:03
【问题描述】:

我有一个启动 WCF 服务的控制台应用程序和一个小型 WPF 应用程序。每当出于测试目的调用 WCF 服务上的方法时,我都会尝试在 WPF 应用程序中显示一个消息框。 我的代码基于this 答案,但同步上下文为空。我该如何解决? 还是有其他/更好的方法来实现这一点?

【问题讨论】:

  • Walkthrough: Creating a WCF Data Service with WPF and Entity Framework,但是在您的情况下,您不需要同步上下文,只需将行注释掉
  • 您确定您的同步上下文是由 GUI 设置的字段吗?如您使用的示例所示;在表单的构造函数中设置字段 synchronisationcontext。然后在服务方法中使用该字段。这些服务方法可能不在 GUI 线程上运行,因此它们没有同步上下文(这就是它们必须同步到 GUI 上下文的原因)。

标签: c# wpf wcf


【解决方案1】:

使用SignalR。大量信息herehereThis article 看起来也很不错。

至于实际代码,创建一个WCF服务并使用NuGet添加对SignalR的引用,然后添加一个hub类:

public class ServiceMonitorHub : Hub
{
}

您还需要添加一个 Owin 启动类来启动 SignalR 集线器:

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

然后,您的服务处理程序可以获得对此集线器的引用并将消息发送到连接到它的所有客户端:

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);
    }

然后您的 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)
        {
        }
    }
}

}

请注意,客户端需要 NuGet SignalR.Clients 包(而不仅仅是 SignalR)。

服务调用中心客户端还有其他方式,this link 显示了其他几种方式。

【讨论】:

    【解决方案2】:

    也许你可以试试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;
        }
    }
    

    要注册 Inspector ,您需要使用 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)
        {
    
        }
    }
    

    然后将行为添加到您的客户端。

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

    【讨论】:

      猜你喜欢
      • 2012-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      • 2022-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多