【问题标题】:How to send updates from server to clients?如何将更新从服务器发送到客户端?
【发布时间】:2015-09-14 14:27:26
【问题描述】:

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

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

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

一个小例子,以防我解释得不好: 服务器在计算机 1 上,有两个客户端,分别在计算机 2 和 3 上。 客户 2 有一辆丰田汽车,客户 3 有一辆宝马汽车。 计算机 1 上的服务器想要告诉客户端 2,它有一辆新车,即 Avenger。

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

感谢您的帮助!

【问题讨论】:

  • 如果我错了,肯定有人可以纠正我,但客户应该会问是否有更新。这不完全是服务器的工作。
  • 您使用什么框架进行服务器/客户端连接? WCF?您是否考虑过使用 Azure 事件中心之类的东西?

标签: c# wpf client-server


【解决方案1】:

您可以尝试实现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());

【讨论】:

  • 如果您解释了 SignalR 如何满足这种架构需求,这将是一个更有帮助的答案
【解决方案2】:

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

  1. 客户端向消息传递通道发送请求,以将自己注册为某种消息/事件/等的订阅者。
  2. 服务器将消息发送到通道以传递给该消息的订阅者。

有很多方法可以处理这个问题。如果您不想在这里重新发明轮子,可以使用一些 Azure 服务(如事件中心或主题)。您还可以让您的服务器应用程序跟踪所有这些事情(IP 地址的更新、订阅兴趣的更新、确保消息不会被多次发送;注意消息的持久性 [确保消息即使在创建消息时客户端处于脱机状态])。

【讨论】:

    【解决方案3】:

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

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

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

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

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

    1. 客户端 A 调用服务器 API 来监听消息
    2. 服务器保持呼叫,等待数据库中的新消息条目
    3. 客户端 B 调用服务器 API 发布新消息
    4. 服务器将消息保存到数据库
    5. 第 2 步中的服务器实例看到新消息
    6. 服务器返回消息给客户端A。

    此外,消息不必存储在数据库中 - 它只取决于您的需要。

    【讨论】:

      【解决方案4】:

      听起来你想跟踪用户 à 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 -使用-mvvm/。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-15
        • 1970-01-01
        • 2012-06-04
        • 2021-08-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-16
        • 2021-12-04
        相关资源
        最近更新 更多