private static void TestSendReceiveRequest(Action <IPEndPoint, UdpClientTransportManager> test)
        {
            using (var server =
                       MsgPack.Rpc.Server.CallbackServer.Create(
                           new MsgPack.Rpc.Server.RpcServerConfiguration()
            {
                PreferIPv4 = true,
                BindingEndPoint = new IPEndPoint(IPAddress.Any, MsgPack.Rpc.Server.CallbackServer.PortNumber),
                MinimumConcurrentRequest = 1,
                MaximumConcurrentRequest = 10,
                MinimumConnection = 1,
                MaximumConnection = 1,
                TransportManagerProvider = s => new MsgPack.Rpc.Server.Protocols.UdpServerTransportManager(s),
                DispatcherProvider = s => new MsgPack.Rpc.Server.Dispatch.CallbackDispatcher(s, (id, args) => args),
                UdpListenerThreadExitTimeout = TimeSpan.FromSeconds(1),
                IsDebugMode = true,
            }
                           )
                   )
            {
                var ipEndPoint = new IPEndPoint(IPAddress.Loopback, MsgPack.Rpc.Server.CallbackServer.PortNumber);

                using (var clientTransportManager = new UdpClientTransportManager(new RpcClientConfiguration()))
                {
                    test(ipEndPoint, clientTransportManager);
                }
            }
        }
 public void TestConnectAsync_Null()
 {
     using (var target = new UdpClientTransportManager(new RpcClientConfiguration()))
     {
         target.ConnectAsync(null);
     }
 }
        public void TestConnectAsync_Success()
        {
            var endPoint = new IPEndPoint(IPAddress.Loopback, 57319);

            var listener = new UdpClient(endPoint);

            try
            {
                using (var target = new UdpClientTransportManager(new RpcClientConfiguration()))
                    using (var result = target.ConnectAsync(endPoint))
                    {
                        Assert.That(result.Wait(TimeSpan.FromSeconds(1)));
                        try
                        {
                            var transport = result.Result;
                            Assert.That(transport.BoundSocket, Is.Not.Null);
                            Assert.That((transport as UdpClientTransport).RemoteEndPoint, Is.EqualTo(endPoint));
                        }
                        finally
                        {
                            result.Result.Dispose();
                        }
                    }
            }
            finally
            {
                listener.Close();
            }
        }
        private static void TestSendReceiveRequestCore(IPEndPoint endPoint, int count, int concurrency)
        {
            _SetUpFixture.EnsureThreadPoolCapacity();

            using (var clientTransportManager = new UdpClientTransportManager(new RpcClientConfiguration()
            {
                PreferIPv4 = true
            }))
            {
                var connectTask = clientTransportManager.ConnectAsync(endPoint);

                if (!connectTask.Wait(Debugger.IsAttached ? Timeout.Infinite : TimeoutMilliseconds))
                {
                    throw new TimeoutException();
                }

                using (var clientTransport = connectTask.Result)
                {
                    for (int i = 0; i < count; i++)
                    {
                        using (var latch = new CountdownEvent(concurrency))
                        {
                            var ids           = Enumerable.Range(i * concurrency, concurrency).ToArray();
                            var args          = Enumerable.Repeat(0, concurrency).Select(_ => Guid.NewGuid().ToString()).ToArray();
                            var idAndArgs     = ids.Zip(args, (id, arg) => new { MessageId = id, Guid = arg.ToString() });
                            var requestTable  = new ConcurrentDictionary <int, string>();
                            var responseTable = new ConcurrentDictionary <int, string>();
                            var exceptions    = new ConcurrentBag <Exception>();

                            if (!Task.Factory.ContinueWhenAll(
                                    idAndArgs.Select(
                                        idAndArg =>
                                        Task.Factory.StartNew(
                                            () =>
                            {
                                var requestContext = clientTransport.GetClientRequestContext();
                                requestTable[idAndArg.MessageId] = idAndArg.Guid;
                                requestContext.SetRequest(
                                    idAndArg.MessageId,
                                    "Dummy",
                                    (responseContext, exception, completedSynchronously) =>
                                {
                                    try
                                    {
                                        if (exception != null)
                                        {
                                            exceptions.Add(exception);
                                        }
                                        else
                                        {
                                            // Server returns args as array, so store only first element.
                                            responseTable[responseContext.MessageId.Value] = Unpacking.UnpackArray(responseContext.ResultBuffer)[0].AsString();
                                        }
                                    }
                                    finally
                                    {
                                        latch.Signal();
                                    }
                                }
                                    );
                                requestContext.ArgumentsPacker.PackArrayHeader(1);
                                requestContext.ArgumentsPacker.Pack(idAndArg.Guid);

                                return(requestContext);
                            }
                                            )
                                        ).ToArray(),
                                    previouses =>
                            {
                                var contexts = previouses.Select(previous => previous.Result).ToArray();
                                foreach (var context in contexts)
                                {
                                    clientTransport.Send(context);
                                }
                            }
                                    ).ContinueWith(
                                    previous =>
                            {
                                if (previous.IsFaulted)
                                {
                                    throw previous.Exception;
                                }

                                // receive
                                if (!latch.Wait(Debugger.IsAttached ? Timeout.Infinite : TimeoutMilliseconds))
                                {
                                    throw new TimeoutException("Receive");
                                }

                                if (exceptions.Any())
                                {
                                    throw new AggregateException(exceptions);
                                }

                                Assert.That(requestTable.Count, Is.EqualTo(concurrency));
                                Assert.That(requestTable, Is.EquivalentTo(responseTable));
                            }
                                    ).Wait(Debugger.IsAttached ? Timeout.Infinite : TimeoutMilliseconds))
                            {
                                throw new TimeoutException();
                            }
                        }
                    }
                }
            }
        }
        private static void TestSendNotifyCore(IPEndPoint endPoint, CountdownEvent arrivalLatch, IProducerConsumerCollection <string> arrivedIds, int count)
        {
            using (var clientTransportManager = new UdpClientTransportManager(new RpcClientConfiguration()
            {
                PreferIPv4 = true
            }))
                using (var connectTask = clientTransportManager.ConnectAsync(endPoint))
                {
                    if (!connectTask.Wait(Debugger.IsAttached ? Timeout.Infinite : TimeoutMilliseconds))
                    {
                        throw new TimeoutException();
                    }

                    using (var clientTransport = connectTask.Result)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            if (arrivalLatch != null)
                            {
                                arrivalLatch.Reset();
                            }

                            var args       = Enumerable.Repeat(0, arrivalLatch.InitialCount).Select(_ => Guid.NewGuid().ToString()).ToArray();
                            var exceptions = new ConcurrentBag <Exception>();

                            if (!Task.Factory.ContinueWhenAll(
                                    args.Select(
                                        arg =>
                                        Task.Factory.StartNew(
                                            () =>
                            {
                                var requestContext = clientTransport.GetClientRequestContext();
                                requestContext.SetNotification(
                                    "Dummy",
                                    (exception, completedSynchronously) =>
                                {
                                    if (exception != null)
                                    {
                                        exceptions.Add(exception);
                                    }

                                    arrivalLatch.Signal();
                                }
                                    );
                                requestContext.ArgumentsPacker.PackArrayHeader(1);
                                requestContext.ArgumentsPacker.Pack(arg);

                                return(requestContext);
                            }
                                            )
                                        ).ToArray(),
                                    previouses =>
                            {
                                var contexts = previouses.Select(previous => previous.Result).ToArray();
                                foreach (var context in contexts)
                                {
                                    clientTransport.Send(context);
                                }
                            }
                                    ).ContinueWith(
                                    previous =>
                            {
                                if (previous.IsFaulted)
                                {
                                    throw previous.Exception;
                                }

                                // receive
                                if (!arrivalLatch.Wait(Debugger.IsAttached ? Timeout.Infinite : TimeoutMilliseconds))
                                {
                                    throw new TimeoutException("Receive");
                                }

                                if (exceptions.Any())
                                {
                                    throw new AggregateException(exceptions);
                                }
                            }
                                    ).Wait(Debugger.IsAttached ? Timeout.Infinite : TimeoutMilliseconds))
                            {
                                throw new TimeoutException();
                            }
                        }
                    }
                }
        }
 /// <summary>
 ///		Initializes a new instance of the <see cref="UdpClientTransport"/> class.
 /// </summary>
 /// <param name="manager">The manager which will manage this instance.</param>
 /// <exception cref="ArgumentNullException">
 ///		<paramref name="manager"/> is <c>null</c>.
 /// </exception>
 public UdpClientTransport(UdpClientTransportManager manager) : base(manager)
 {
 }