WCF发布是正确的选择吗

本文关键字:选择 WCF | 更新日期: 2023-09-27 18:25:34

我已经创建了一个具有TCP绑定的本地WCF服务。当我的服务突然中断时,我想处理这个案子。我知道如何检查客户端的服务何时停止,但我不知道如何检查服务何时恢复在线。

简而言之,我希望我的客户端在服务重新启动时自动创建新的正确连接
在查看了互联网后,我发现了WCF公告功能,但我没有找到关于如何使用公告功能的明确示例。

请注意,客户端连接对象(服务)是由Visual Studio通过输入服务引用自动创建的,而不是由我自己创建的
我的服务有一个静态IP地址,所有客户端都将在本地网络上。

我的问题是,WCF发布是正确的选择,还是有其他解决方案?

WCF发布是正确的选择吗

有两种方法可以做你需要做的事情:

由于您的服务有一个静态IP地址,因此您可以使用旧的方法,即在客户端上设置一个"检查是否联机"计时器事件,该事件在与服务的连接丢失时启动,并通过在WCF服务上调用一个只回复True/All-OK的特定方法,不断戳目标以查看服务何时重新启动这种方法的问题有很多:

  • 您需要有一种方法来更改每个客户端配置上的IP地址,这可能会造成维护噩梦
  • 如果有许多客户端应用程序每隔几秒钟轮询一次服务,看看它是否再次启动,那么您的服务可能会受到严重打击
  • 当服务再次可用时,您将有一个延迟,即轮询间隔的最长持续时间

因此,使用WCF发现方法会更好,因为这样您的客户端将等待服务再次联机,宣布它已准备就绪,并且不会因不必要的流量而堵塞本地网络。在以下网站上,有关于如何使用WCF发现功能的示例和解释:

  • WCF常规发现页面,此处包含特定的客户端实现
  • Visual Studio页面中的公告示例
  • 另一个包含示例和完整应用程序的网站,其中包含您可以查看的配置文件

希望所有这些页面都能以您的语言提供。

为了使公告生效,服务器端需要在服务器端配置文件(如)的服务行为中添加标签

   <serviceBehaviors>
    <behavior name="MyServiceBehavior">
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceDiscovery>
        <announcementEndpoints>
          <endpoint kind="udpAnnouncementEndpoint"/>
        </announcementEndpoints>
      </serviceDiscovery>   
      <serviceMetadata />
    </behavior>
    </serviceBehaviors>

并在服务器配置文件的服务标签中添加一个新的端点,就像这个一样

<services>
  <service behaviorConfiguration="MyServiceBehavior" name="TestService.Service">
    <endpoint binding="netTcpBinding" bindingConfiguration="myBinding" name="NetTcpService" contract="TestService.IService" />
    <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" name="NetTcpMex" contract="IMetadataExchange"/>
    <endpoint name="udpDiscoveryEpt" kind="udpDiscoveryEndpoint"/>
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://[replace with ip address]:8080/Service" />
      </baseAddresses>
    </host>
  </service>

重点是我们在服务标签中添加的终点

<endpoint name="udpDiscoveryEpt" kind="udpDiscoveryEndpoint"/>

对于客户端

  static void Main(string[] args)
    {

        AnnouncementService announcementService = new AnnouncementService();
        announcementService.OnlineAnnouncementReceived += service_OnlineAnnouncementReceived;
        announcementService.OfflineAnnouncementReceived += service_OfflineAnnouncementReceived;
        using(var announcementServiceHost=new ServiceHost(announcementService))
        {
            announcementServiceHost.AddServiceEndpoint(new UdpAnnouncementEndpoint());
            announcementServiceHost.Open();
            Console.WriteLine("Please enter to exit'n'n");
            Console.ReadLine();
        }
    }
    static void service_OfflineAnnouncementReceived(object sender, AnnouncementEventArgs e)
    {
        Console.WriteLine("Service Offline");
    }
    static void service_OnlineAnnouncementReceived(object sender, AnnouncementEventArgs e)
    {
        Console.WriteLine("Service Online");
    }

最重要的一点是

     using(var announcementServiceHost=new ServiceHost(announcementService))
        {
            announcementServiceHost.AddServiceEndpoint(new UdpAnnouncementEndpoint());
            announcementServiceHost.Open();
            Console.WriteLine("Please enter to exit'n'n");
            Console.ReadLine();
        }

其实际上开始监听服务通告事件。