【问题标题】:WCF service discovery issue, take much time to return results?WCF 服务发现问题,需要很长时间才能返回结果?
【发布时间】:2012-05-03 06:51:07
【问题描述】:

我有一个 WCF 服务器库和客户端 [Winform],我使用自托管 winform 启动服务器。

我想让客户端发现 LAN 上的活动服务器,以另一种方式获取列表中的在线服务器 IPAddresses。我试过DiscoveryClientUdpDiscoveryEndpoint 并且成功了这是代码:

客户端[Winform]:

 private void button1_Click(object sender, EventArgs e)
    {
        DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
        FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(IFileManager)));
        foreach (EndpointDiscoveryMetadata ep in findResponse.Endpoints)
        {
            listView1.Items.Add(ep.Address.ToString());
        }
    }   

服务器[Winform]:

ServiceHost host = new ServiceHost(typeof(MainService));
private void button1_Click(object sender, EventArgs e)
    {
        if (button1.Text == "Start")
        {
            host.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
            host.AddServiceEndpoint(new UdpDiscoveryEndpoint());
            host.Open();
            button1.Text = "Stop";
        }
        else
        {
            host.Close();
            button1.Text = "Start";
        }
    }

但它并没有像我预期的那样工作!

  • 为什么我必须给 ClientDiscovery 一个特定的标准?我有很多接口,我只需要主机地址,而不是接口的地址!
  • 获取列表需要花费太多时间 [大约 15-20 秒],不是应该很快吗?

    更新:
    在我使用 WCF 之前,我已经在 TCP 套接字上开发了一个服务器发现,我使用了 try/catch 的并行线程来连接和循环 255 个 IP 地址,例如:(192.168.1.X),我在 LAN 5 服务器上尝试过[PC] ,结果是如此完美和快速,我坐了一个超时(3 秒)
    但在 WCF 上,我不知道我将如何实现这一点!!

  • 【问题讨论】:

      标签: c# wcf service-discovery


      【解决方案1】:

      为什么我必须给 ClientDiscovery 一个特定的标准?我有很多接口,我只需要主机地址,而不是接口的地址!

      这就是解耦的重点,您需要的所有服务都在单个服务器上这一事实是一个实现细节。也就是说,您可以将您的客户端耦合到您的特定架构,使用从发现过程的第一个结果收到的 MEX 地址中的信息手动创建客户端。

      获取列表需要太多时间 [大约 15-20 秒],不是假设 要快吗?

      不,如果您要查找服务的多个实例,则发现不应该很快:默认超时为 20 秒。现在,如果您只需要该服务的一个实例(大多数情况下),那么您可以通过将 FindCriteria 的 MaxResults 属性设置为 1 来明确告诉客户端在找到第一个服务后停止。这比等待超时。

      有关更多信息,您可以查看此excellent article

      更新

      您可以通过FindCriteria.Duration 属性设置超时。

      更新 2

      您可以通过 MEX 端点获得有关该服务的所有信息。您可以将 MetadataExchangeClient 与您从发现中获得的 MEX 地址一起使用,并使用您返回的 MetadataSet 中的信息(请参阅http://msdn.microsoft.com/en-us/library/ms730243.aspx,检索服务元数据),但我不确定您需要什么样的信息会回来的,因为我从来没有这样用过。

      这取决于您所说的状态:WS-discovery 没有我所知道的状态概念,无论服务是否存在。对此概念的任何其他解释,您必须将自己实现为服务中的操作。

      【讨论】:

      • 我实际上需要获得所有在线服务器,为什么它假设它很慢! NetSupport,PcAnyWhere,一些多人游戏怎么样..我认为它应该很快,请看看我更新了我的问题。
      • 嗯,你知道我如何让服务发现返回额外的信息,比如计算机名称和状态!
      • @MurHafSoz 答案再次更新 :) 请注意,服务发现不是服务器发现:所有额外的工作或结构使其成为您必须自己实现的服务器发现机制。
      • 状态是指我添加的自定义附加响应,例如如果此服务已经连接了客户端,它会返回 BUSY。
      • @MurHafSoz 那么是的,您必须为此实施一个操作,在该操作中,您使用已连接的业务定义检查客户端是否已连接(例如,最后一个活动 x 秒)。
      【解决方案2】:

      如果您将DiscoveryClientFindAsync() 方法与FindProgressChangedFindCompleted 事件一起使用,而不是使用同步的Find() 方法,您会发现FindProgressChanged 事件会立即被触发端点结果进来,这意味着您可以立即访问它们,而不必等待搜索结束。当FindCompleted 触发时,您将知道搜索结束。

      对我来说,我的所有网络客户端使用此方法通过FindProgressChanged 事件进行报告不会超过几秒钟。

      哦,如果您出于任何原因需要取消搜索(例如,有人在搜索过程中关闭了您的对话框),请调用 DiscoveryClientCancelAsync() 方法。

      【讨论】:

      • 对我来说,这个答案实际上回答了这个问题。接受的答案只是说 OP 在没有适当解释的情况下是错误的。发现速度很快,使用 Sync 方法是延迟响应的原因。
      • @DavidRitchie 确实如此。但是,我在被问到这个问题将近 3 年后才回答了这个问题,并且当时接受的答案已经被接受了。当一个更好的答案出现时,很多人不会费心回去改变他们接受的答案,因为他们早就解决了原来的问题。没关系,不过,我倾向于发布我的答案是为了帮助人们,而不是为了分数。 :)
      猜你喜欢
      • 2014-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-10
      • 2020-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多