void RemoveOnlineService(EndpointDiscoveryMetadata endpointDiscoveryMetadata)
        {
            if (endpointDiscoveryMetadata == null)
            {
                throw new Exception("Metadata is invalid.");
            }

            var mexCriteria = new FindCriteria(typeof(IMetadataExchange));

            if (mexCriteria.IsMatch(endpointDiscoveryMetadata))
            {
                return;
            }

            lock (this._onlineServices)
            {
                XElement delService = endpointDiscoveryMetadata.Extensions.FirstOrDefault(x =>
                                                                                          x.Name.LocalName == "Id" && x.Value != "") ??
                                      endpointDiscoveryMetadata.Extensions.FirstOrDefault(x =>
                                                                                          x.Name.LocalName == "Contract" && x.Value != "");
                if (delService == null)
                {
                    return;
                }

                this._onlineServices.Remove(delService.Value);
            }

            PrintDiscoveryMetadata(endpointDiscoveryMetadata, "Removing");
        }
        // The following are helper methods required by the Proxy implementation
        void AddOnlineService(EndpointDiscoveryMetadata endpointDiscoveryMetadata)
        {
            if (endpointDiscoveryMetadata == null)
            {
                throw new Exception("Metadata is invalid.");
            }

            var mexCriteria = new FindCriteria(typeof(IMetadataExchange));

            if (mexCriteria.IsMatch(endpointDiscoveryMetadata))
            {
                return;
            }

            if (endpointDiscoveryMetadata.Extensions.Count == 0)
            {
                throw new Exception("Endpoint is invalid.");
            }

            string serviceContract = string.Empty;
            string serviceId       = string.Empty;

            foreach (XElement customMetadata in endpointDiscoveryMetadata.Extensions)
            {
                switch (customMetadata.Name.LocalName)
                {
                case "Contract":
                    serviceContract = customMetadata.Value;
                    break;

                case "Id":
                    serviceId = customMetadata.Value;
                    break;
                }
            }

            if (serviceContract == string.Empty)
            {
                throw new Exception("Service Contract is missing.");
            }

            lock (this._onlineServices)
            {
                if (serviceId == string.Empty)
                {
                    serviceId = serviceContract;
                }
                else if (this._onlineServices.ContainsKey(serviceId))
                {
                    throw new Exception("Service Id is duplicated.");
                }

                this._onlineServices[serviceId] = endpointDiscoveryMetadata;
            }

            PrintDiscoveryMetadata(endpointDiscoveryMetadata, "Adding");
        }
        private void OnOfflineAnnouncement(object sender, AnnouncementEventArgs e)
        {
            EndpointDiscoveryMetadata metadata = e.EndpointDiscoveryMetadata;

            FindCriteria criteria = new FindCriteria(typeof(T));

            if (criteria.IsMatch(metadata))
            {
                // 指定类型的服务下线
                if (cache.Contains(metadata.Address.Uri))
                {
                    cache.Remove(metadata);
                    Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Announcement endpoint offline : {0} - {1}", metadata.GetSpecifiedName(), metadata.Address.Uri));
                }
            }
        }
        /// <summary>
        /// Override this method to handle an offline announcement message.
        /// </summary>
        /// <param name="messageSequence">The discovery message sequence.</param>
        /// <param name="endpointDiscoveryMetadata">The endpoint discovery metadata.</param>
        /// <param name="callback">The callback delegate to call when the operation is completed.</param>
        /// <param name="state">The user-defined state data.</param>
        /// <returns>
        /// A reference to the pending asynchronous operation.
        /// </returns>
        protected override IAsyncResult OnBeginOfflineAnnouncement(DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata endpointDiscoveryMetadata, AsyncCallback callback, object state)
        {
            if (endpointDiscoveryMetadata == null)
            {
                throw new ArgumentNullException("endpointDiscoveryMetadata");
            }

            FindCriteria criteria = new FindCriteria(typeof(T));

            if (criteria.IsMatch(endpointDiscoveryMetadata))
            {
                // 指定类型的服务下线
                if (cache.Contains(endpointDiscoveryMetadata.Address.Uri))
                {
                    cache.Remove(endpointDiscoveryMetadata);
                    Console.WriteLine(string.Format(CultureInfo.InvariantCulture, "Discovery proxy endpoint offline : {0} - {1}", endpointDiscoveryMetadata.GetSpecifiedName(), endpointDiscoveryMetadata.Address.Uri));
                }
            }

            return(new CompletedAsyncResult(callback, state));
        }
 public bool Matches(EndpointDiscoveryMetadata endpoint)
 {
     return(criteria == null || criteria.IsMatch(endpoint));
 }