public async Task <TInterface> GetChannelAsync <TInterface>(bool forceReconnect = false) where TInterface : class
        {
            if (!HashChannel <TInterface>())
            {
                ThrowNotFound <TInterface>();
            }

            await slim.WaitAsync();

            try
            {
                if (session == null || session.IsDisposed || forceReconnect)
                {
                    channels.Clear();
                    await ConnectAsync();
                }

                if (channels.TryGetValue(typeof(TInterface), out var value))
                {
                    return((TInterface)value);
                }

                var channel = session.CreateChannel <TInterface>();
                channels[typeof(TInterface)] = channel;
                return(channel);
            }
            finally
            {
                slim.Release();
            }
        }
Exemple #2
0
        public async Task HostAndCreateChannel()
        {
            // Create host
            var host = new ProtocolHost();

            // Load controllers from reference.
            host.LoadFromReference <ProtocolHostTests>();

            // Register object to dependency injection. Just an example. This test doesn't require this.
            host.Resolver.Register(new CalculatorParameter()
            {
                First = 10
            });

            // Start server. Should be skiped on client side.
            var serverTask = host.StartServerAsync("127.0.0.1", 90, CancellationToken.None);


            IResolverSession clientSession = null;

            // Handle client connections.
            host.ClientConnected += (h, s) =>
            {
                // Session of client connected to server.
                clientSession = s;
            };

            // Can be used in Program.Main to run server. Task ends when server socket stops listening.
            // await serverTask;


            // Connect client. Should be skiped on server side.
            var session = await host.StartClientAsync("127.0.0.1", 90);

            // Create channel of IAddMethod interface on client side and call method from client to server.
            var serverSideCalculator = session.CreateChannel <IAddMethod>();

            // Create Stopwatch for performance measure.
            var watch = Stopwatch.StartNew();

            var tasks = new List <Task <CalculatorResult> >();

            // Run asynchronous 10k requests.
            for (int i = 0; i < 10000; i++)
            {
                // From client call method on server side.
                var task = serverSideCalculator.AddAsync(10, 9);
                tasks.Add(task);
            }

            // Wait when all 10k requests ends.
            var serverResults = await Task.WhenAll(tasks);

            // Stop Stopwatch.
            watch.Stop();

            // Check result.
            foreach (var serverResult in serverResults)
            {
                Assert.AreEqual(19, serverResult.Result);
            }

            // Check if elapsed time is less than one second.
            Assert.IsTrue(watch.ElapsedMilliseconds < 1000, $"Elapsed time is more than one second. Elapsed time in milliseconds: {watch.ElapsedMilliseconds}");

            // Since we created both server and client from same ProtocolHost, they have same controllers that we can call.
            // Create channel of IAddMethod interface on server side and call method from server to client.
            var clientSideCalculator = clientSession.CreateChannel <IAddMethod>();
            var clientResult         = await clientSideCalculator.AddAsync(10, 10);

            Assert.AreEqual(20, clientResult.Result);

            // Close client connection.
            session.Dispose();
        }