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

问题描述 投票:0回答:4

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

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

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

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

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

感谢您的帮助!

c# wpf client-server
4个回答
7
投票

你可以尝试实现 SignalR。这是一个很棒的库,它使用网络套接字将数据推送到客户端。

编辑:

SignalR 可以通过允许您在控制台应用程序(服务器)上设置 WPF 应用程序(客户端)可以连接到的集线器来帮助您解决问题。当客户端启动时,您将向指定的集线器注册它们。当服务器发生变化时,您可以从服务器 Hub 推送到客户端。客户端将从服务器接收信息,并允许您按您认为合适的方式处理它。

一些代码的粗略模型:

namespace 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());

2
投票

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

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

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


2
投票

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

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

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

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

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

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

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


0
投票

听起来您想像 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/.

© www.soinside.com 2019 - 2024. All rights reserved.