如何从服务器向客户端发送更新?

时间:2015-09-14 14:27:27

标签: c# wpf client-server

我正在构建一个c#/ wpf项目。 它的架构是这样的:

  • 一个控制台应用程序,它将位于服务器端的虚拟机(或我的家用计算机)上。
  • 将成为客户端应用程序的wpf应用程序。

现在我的问题是这个 - 我希望服务器能够向客户端发送更改。例如,如果我对客户端ABC进行了更改,我希望服务器知道如何在客户端计算机上调用服务。 问题是,我不知道服务器将如何呼叫客户端。

一个小例子,以防我没有解释清楚: 服务器位于计算机1上,计算机2和3上有两个客户端。 客户2有一辆丰田汽车,客户3有一辆宝马汽车。 计算机1上的服务器想要告诉客户2它有一辆新车,复仇者。

如何在客户端上跟踪和呼叫服务? 我想在数据库中保存他们的IP地址(从cmd调用ipconfig) - 但是不是基于他们连接的WI-FI /网络吗?

感谢您的帮助!

4 个答案:

答案 0 :(得分:5)

您可以尝试实施SignalR。它是一个很棒的库,它使用Web套接字将数据推送到客户端。

编辑:

SignalR可以通过允许您在控制台应用程序(服务器)上设置WPF应用程序(客户端)可以连接的集线器来帮助您解决问题。当客户启动时,您将使用指定的Hub注册它们。当服务器上的某些内容发生变化时,您可以从服务器中心推送到客户端。客户端将从服务器接收信息,并允许您根据需要处理它。

一些代码的粗略模型:

namepsace Server{}
    public class YourHub : Hub {
        public void SomeHubMethod(string userName) { 
            //clientMethodToCall is a method in the WPF application that
            //will be called. Client needs to be registered to hub first.
            Clients.User(userName).clientMethodToCall("This is a test.");

           //One issue you may face is mapping client connections.
           //There are a couple different ways/methodologies to do this.
           //Just figure what will work best for you.
         }
    }
}

namespace Client{
    public class HubService{          

      public IHubProxy CreateHubProxy(){
          var hubConnection = new HubConnection("http://serverAddress:serverPort/");
          IHubProxy yourHubProxy = hubConnection.CreateHubProxy("YourHub");
          return yourHubProxy;
        }
    }

}

然后在你的WPF窗口中:

var hubService = new HubService();
var yourHubProxy = hubService.CreateHubProxy();
yourHubProxy.Start().Wait();
yourHubProxy.On("clientMethodToCall", () => DoSometingWithServerData());

答案 1 :(得分:2)

您需要为客户端创建某种订阅模型,以便服务器处理发布 - 订阅频道(请参阅http://www.enterpriseintegrationpatterns.com/patterns/messaging/PublishSubscribeChannel.html)。基本架构是这样的:

  1. 客户端向消息传递通道发送请求,将其自身注册为某种消息/事件/等的订阅者。
  2. 服务器将消息发送到要传递给该消息的订阅者的频道。
  3. 有很多方法可以解决这个问题。如果您不想在此重新发明轮子,可以使用某些Azure服务(如Event hub或Topic)。您还可以让您的服务器应用程序跟踪所有这些事情(更新IP地址,更新订阅兴趣,确保不会多次发送消息;处理消息持久性[确保消息即使是创建消息时客户端处于脱机状态])。

答案 2 :(得分:2)

一般而言,无论您选择哪种解决方案都会遇到一个常见问题 - 客户端隐藏在防火墙后面并拥有动态IP地址。这使得服务器推送到客户端很困难(我听说技术声称要克服这个但却没有看到任何行动)。

实际上,客户端会说话,服务器会监听和响应。但是,您可以使用此方法来模拟推送; 1.轮询(客户定期询问信息) 2.长轮询(客户端要求提供信息,服务器保留请求,直到信息到达或发生超时) 3.套接字(客户端请求服务器连接,用于一段时间的双向通信)。

了解这些条款后,您的下一个选择是自己编写或使用第三方服务(azure,amazon,other)为您提供信息。我个人喜欢长时间轮询,因为它很容易实现。在我的应用程序中,我有以下设置。

  • Azure上的Web API服务器和侦听消息请求的端点
  • 服务器代码中的一个简单循环,它每100毫秒检查数据库中的新消息。
  • 调用API,处理响应的客户端。

如上所述,有很多方法可以做到这一点。在您的特定情况下,一种方法如下。

  1. 客户端A调用服务器API以侦听消息
  2. 服务器保持呼叫,等待数据库中的新消息条目
  3. 客户端B调用服务器API发布新消息
  4. 服务器将消息保存到数据库
  5. 步骤2中的服务器实例看到新消息
  6. 服务器向客户端A返回消息。
  7. 此外,消息不必存储在数据库中 - 它只取决于您的需求。

答案 3 :(得分:0)

您希望跟踪用户{la https://www.simple-talk.com/dotnet/asp.net/tracking-online-users-with-signalr/,但在http://www.codeproject.com/Articles/804770/Implementing-SignalR-in-Desktop-Applications或damienbod.wordpress.com/2013/11/20/signalr-a-complete意义上的桌面应用中-wpf-client-using-mvvm /。