public async Task DualServer_DiscoveryClient_BeforeServerStart_Should_Discover()
        {
            var server            = new LightweightRpcServer();
            var endPoint          = new TcpRpcEndPoint("localhost", "127.0.0.1", ClientServerTestsBase.TcpTestPort, false);
            var discoveryEndPoint = new LightweightDiscoveryEndPoint(endPoint.GetConnectionInfo(server.ServerId));

            server.AddEndPoint(endPoint);
            server.AddEndPoint(discoveryEndPoint);

            var server2            = new LightweightRpcServer();
            var endPoint2          = new TcpRpcEndPoint("localhost", "127.0.0.1", ClientServerTestsBase.TcpTestPort + 1, false);
            var discoveryEndPoint2 = new LightweightDiscoveryEndPoint(endPoint2.GetConnectionInfo(server2.ServerId));

            server2.AddEndPoint(endPoint2);
            server2.AddEndPoint(discoveryEndPoint2);

            server.PublishSingleton <ISimpleService>();
            server2.PublishSingleton <ISimpleService2>();

            var discoveryClient = new LightweightDiscoveryClient(loggerFactory.CreateLogger <LightweightDiscoveryClient>());

            var  eventDiscoveredServices = new List <DiscoveredService>();
            bool serviceLost             = false;

            discoveryClient.ServiceDiscovered += (s, e) => eventDiscoveredServices.Add(e.DiscoveredService);
            discoveryClient.ServiceLost       += (s, e) => serviceLost = true;

            using var discoveryCts = new CancellationTokenSource();
            var discoveryTask = discoveryClient.FindServicesAsync(discoveryCts.Token);
            await Task.Delay(100);

            server.Start();
            server2.Start();
            try
            {
                await Task.Delay(2000);

                Assert.IsFalse(serviceLost);
                var discoveredServices = discoveryClient.DiscoveredServices;
                Assert.AreEqual(2, discoveredServices.Count);
                Assert.AreEqual(2, eventDiscoveredServices.Count);

                discoveryCts.Cancel();
                await discoveryTask.DefaultTimeout();
            }
            finally
            {
                await server.ShutdownAsync();

                await server2.ShutdownAsync();
            }
        }
        public async Task Multicast_Singletons_ShouldReturn_Published()
        {
            var server         = new LightweightRpcServer();
            var connectionInfo = new RpcConnectionInfo(new Uri("test://test"));
            var endPoint       = new LightweightDiscoveryEndPoint(connectionInfo);

            server.AddEndPoint(endPoint);

            server.PublishSingleton <ISimpleService>();
            server.PublishSingleton <ISimpleService2>();

            server.Start();
            try
            {
                using var client = new UdpClient(AddressFamily.InterNetwork);
                client.Client.Bind(new IPEndPoint(IPAddress.Any, 0));
                client.JoinMulticastGroup(LightweightDiscoveryEndPoint.DefaultMulticastAddress);

                // Receive early
                var receiveTask = client.ReceiveAsync();

                // Build request
                byte[] requestData = LightweightStubHelper.GetRequestData(ServiceDiscoveryOperations.GetPublishedSingletons, 0, new RpcRequest(), this.serializer);

                // Send it
                var discoveryEp = new System.Net.IPEndPoint(LightweightDiscoveryEndPoint.DefaultMulticastAddress, LightweightDiscoveryEndPoint.DefaultDiscoveryPort);
                var bytesSent   = await client.SendAsync(requestData, requestData.Length, discoveryEp);

                Assert.AreEqual(requestData.Length, bytesSent);

                // Wait for response
                var receiveRes = await receiveTask.DefaultTimeout();

                var response = LightweightStubHelper.GetResponseFromData <RpcPublishedSingletonsResponse>(serializer, receiveRes.Buffer);
                Assert.NotNull(response);

                // And check it
                Assert.NotNull(response);
                Assert.AreEqual(2, response.Services.Length);
            }
            finally
            {
                await server.ShutdownAsync();
            }
        }