Exemplo n.º 1
0
        public static ServiceHost <T> CreateDiscoverableHost <T>(Uri scope = null) where T : class
        {
            ServiceHost <T> host = ServiceModelEx.DiscoveryFactory.CreateDiscoverableHost <T>(scope);

            DiscoveryRequestService requestService = new DiscoveryRequestService(host.Description.Endpoints.UnsafeToArray <ServiceEndpoint>());

            ServiceHost requestHost           = new ServiceHost(requestService);
            Uri         requestServiceAddress = new Uri(DiscoveryHelper.AvailableTcpBaseAddress.AbsoluteUri + typeof(T) + "/" + "DiscoveryEndpoint");

            requestHost.AddServiceEndpoint(typeof(IDiscovery), DiscoveryFactory.Binding, requestServiceAddress);

            host.Opened += delegate
            {
                try
                {
                    requestHost.Open();

                    IDiscoverySubscription pubsubProxy = ChannelFactory <IDiscoverySubscription> .CreateChannel(DiscoveryFactory.Binding, Address.DiscoverySubscription);

                    pubsubProxy.Subscribe(requestServiceAddress.AbsoluteUri);
                    (pubsubProxy as ICommunicationObject).Close();
                }
                catch
                {
                    Trace.WriteLine("Could not subscribe to discovery requests for service " + typeof(T));
                }

                IAnnouncements announcementsProxy = ChannelFactory <IAnnouncements> .CreateChannel(DiscoveryFactory.Binding, Address.Announcements);

                PublishAvailabilityEvent(host.Description.Endpoints.ToArray(), announcementsProxy.OnHello);
            };

            host.Closing += delegate
            {
                try
                {
                    IDiscoverySubscription pubsubProxy = ChannelFactory <IDiscoverySubscription> .CreateChannel(DiscoveryFactory.Binding, Address.DiscoverySubscription);

                    pubsubProxy.Unsubscribe(requestServiceAddress.AbsoluteUri);
                    (pubsubProxy as ICommunicationObject).Close();
                    requestHost.Close();
                }
                catch
                {
                    Trace.WriteLine("Could not unsubscribe to discovery requests for service " + typeof(T));
                }
                IAnnouncements announcementsProxy = ChannelFactory <IAnnouncements> .CreateChannel(DiscoveryFactory.Binding, Address.Announcements);

                PublishAvailabilityEvent(host.Description.Endpoints.ToArray(), announcementsProxy.OnBye);
            };
            return(host);
        }
Exemplo n.º 2
0
 public void MultiThreadIsSafe()
 {
     using (var cts = new CancellationTokenSource(Utils.TestTimeoutMs))
     {
         var delayedException = new Utils.DelayedException();
         using (var svc1 = MakeAgent(1))
             using (var svc2 = MakeAgent(2))
             {
                 for (int i = 0; i < 1000; ++i)
                 {
                     {
                         var category = "DisposeInHandler" + i;
                         svc1.PublishAsync(category, "");
                         svc2.PublishAsync(category, "");
                         IDiscoverySubscription sub = svc2.Subscribe(category);
                         sub.Updated +=
                             delayedException.Wrap <IDiscoverySubscription>(
                                 subscription =>
                         {
                             Assert.True(subscription.Resources.Count() >= 0);
                             subscription.Dispose();
                         });
                     }
                     {
                         var category = "DisposeInOtherThread" + i;
                         svc1.PublishAsync(category, "");
                         svc2.PublishAsync(category, "");
                         IDiscoverySubscription sub = svc2.Subscribe(category);
                         Task.Delay(random_.Next(0, 200)).ContinueWith(
                             delayedException.Wrap <Task>(
                                 _ =>
                         {
                             Assert.True(sub.Resources.Count() >= 0);
                             sub.Dispose();
                         }));
                     }
                 }
             }
         Thread.Sleep(200);
         delayedException.Rethrow();
     }
 }
Exemplo n.º 3
0
        // Run a query and wait for the predicate to be satisfied.
        // Return the list of resources which satisfied the predicate or null if canceled before the predicate was satisfied.
        public static IEnumerable <IDiscoveryResource> QueryAndWaitForResourcesPredicate(
            IDiscoverySubscription discovery, Func <IEnumerable <IDiscoveryResource>, bool> pred, CancellationToken token)
        {
            // Check optimistically before subscribing to the discovery event.
            var resources = discovery.Resources;

            if (pred(resources))
            {
                return(resources);
            }
            if (token.IsCancellationRequested)
            {
                return(null);
            }
            using (var wakeUp = new AutoResetEvent(false))
            {
                Action <IDiscoverySubscription> onChange = (IDiscoverySubscription sender) => wakeUp.Set();

                using (var unregisterCancel = token.Register(() => wakeUp.Set()))
                    using (var unregisterWatch = new RaiiGuard(() => discovery.Updated += onChange, () => discovery.Updated -= onChange))
                    {
                        while (true)
                        {
                            // Check before waiting on the event so that updates aren't missed.
                            resources = discovery.Resources;
                            if (pred(resources))
                            {
                                return(resources);
                            }
                            wakeUp.WaitOne(); // wait for cancel or update
                            if (token.IsCancellationRequested)
                            {
                                return(null);
                            }
                        }
                    }
            }
        }
Exemplo n.º 4
0
        public void Run(string username, IPAddress broadcastAddress)
        {
            _username        = username;
            _localAddrString = GetLocalIPAddress().ToString();
            _chatServer      = new TcpListener(IPAddress.Any, ChatPort);
            _chatServer.Start();
            Task.Run(ListenForConnections);

            // Initialize the discovery agent
            _discoveryAgent = new PeerDiscoveryAgent(new UdpPeerDiscoveryTransport(broadcastAddress, DiscoveryPort));

            // Publish a resource exposing the local IP address for connections and the user name as an attribute.
            var connection = GetLocalIPAddress().ToString();
            var attributes = new Dictionary <string, string> {
                [NameKey] = username
            };

            _discoveryAgent.PublishAsync(ParticipantCategory, connection, attributes);

            // Subscribe to other participant resources.
            _discoverySubscription          = _discoveryAgent.Subscribe(ParticipantCategory);
            _discoverySubscription.Updated +=
                (IDiscoverySubscription subscription) =>
            {
                // Parse discovered resources.
                var activePeers = new Dictionary <IPAddress, string>();
                foreach (var res in subscription.Resources)
                {
                    if (res.Connection == _localAddrString)
                    {
                        // Exclude the local resource.
                        continue;
                    }
                    try
                    {
                        var address = IPAddress.Parse(res.Connection);
                        var name    = res.Attributes[NameKey];
                        activePeers.Add(address, name);
                    }
                    catch (Exception e)
                    {
                        // Invalid resource format, or multiple resources per host.
                        Debug.WriteLine($"Invalid resource: {e}");
                        continue;
                    }
                }

                // Create reader connections to the active peers.
                RefreshReaderConnections(activePeers);
            };

            // Loop waiting for input.
            Console.CursorTop = Console.WindowHeight;
            Console.Write(Prompt);
            while (true)
            {
                string message = Console.ReadLine();
                PostLocalMessageToConsole(message);
                PostLocalMessageToPeers(message);
            }
        }