public Connection(TcpRpcServer server, TcpClient client, FramePump pump, OutboundTcpEndpoint outboundEp, RpcEngine.RpcEndpoint inboundEp)
            {
                Client     = client;
                Pump       = pump;
                OutboundEp = outboundEp;
                InboundEp  = inboundEp;

                PumpRunner = new Thread(o =>
                {
                    try
                    {
                        Thread.CurrentThread.Name = $"TCP RPC Server Thread {Thread.CurrentThread.ManagedThreadId}";

                        Pump.Run();
                    }
                    finally
                    {
                        OutboundEp.Dismiss();
                        InboundEp.Dismiss();
                        Pump.Dispose();
                        lock (server._reentrancyBlocker)
                        {
                            --server.ConnectionCount;
                            server._connections.Remove(this);
                        }
                    }
                });
            }
Exemple #2
0
        async Task Connect(string host, int port)
        {
            await ConnectAsync(host, port);

            _pump             = new FramePump(_client.GetStream());
            _outboundEndpoint = new OutboundTcpEndpoint(this, _pump);
            _inboundEndpoint  = _rpcEngine.AddEndpoint(_outboundEndpoint);
            _pumpThread       = new Thread(() =>
            {
                try
                {
                    Thread.CurrentThread.Name = $"TCP RPC Client Thread {Thread.CurrentThread.ManagedThreadId}";

                    _pump.Run();
                }
                finally
                {
                    _outboundEndpoint.Dismiss();
                    _inboundEndpoint.Dismiss();
                    _pump.Dispose();
                }
            });

            _pump.FrameReceived += _inboundEndpoint.Forward;
            _pumpThread.Start();
        }
            public void Start()
            {
                Pump = new FramePump(_stream);

                foreach (var tracer in _tracers)
                {
                    Pump.AttachTracer(tracer);
                }
                _tracers.Clear();

                OutboundEp          = new OutboundTcpEndpoint(_server, Pump);
                InboundEp           = _server._rpcEngine.AddEndpoint(OutboundEp);
                Pump.FrameReceived += InboundEp.Forward;

                State = ConnectionState.Active;

                PumpRunner = new Thread(o =>
                {
                    try
                    {
                        Thread.CurrentThread.Name = $"TCP RPC Server Thread {Thread.CurrentThread.ManagedThreadId}";

                        Pump.Run();
                    }
                    catch (ThreadInterruptedException)
                    {
                        Logger.LogError($"{Thread.CurrentThread.Name} interrupted at {Environment.StackTrace}");
                    }
                    finally
                    {
                        OutboundEp.Dismiss();
                        InboundEp.Dismiss();
                        Pump.Dispose();
                        Client.Dispose();
                        lock (_server._reentrancyBlocker)
                        {
                            --_server.ConnectionCount;
                            _server._connections.Remove(this);
                            State = ConnectionState.Down;
                            _server.OnConnectionChanged?.Invoke(_server, new ConnectionEventArgs(this));
                        }
                    }
                });
                PumpRunner.Start();
            }
        public void PipedFramePump()
        {
            int UnpackFrame(WireFrame frame)
            {
                int count = frame.Segments.Count;

                for (int i = 0; i < count; i++)
                {
                    Assert.AreEqual(i + 1, frame.Segments[i].Length);
                }

                return(count);
            }

            WireFrame PackFrame(int value)
            {
                var segments = new Memory <ulong> [value];

                for (int i = 0; i < value; i++)
                {
                    ulong[] a = new ulong[i + 1];
                    segments[i] = new Memory <ulong>(a);
                }

                return(new WireFrame(segments));
            }

            Thread rxRunner = null;

            using (var server = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.None))
                using (var client = new AnonymousPipeClientStream(PipeDirection.In, server.ClientSafePipeHandle))
                    using (var bc = new BlockingCollection <int>(8))
                    {
                        server.ReadMode = PipeTransmissionMode.Byte;
                        client.ReadMode = PipeTransmissionMode.Byte;

                        using (var txPump = new FramePump(server))
                            using (var rxPump = new FramePump(client))
                            {
                                rxRunner = new Thread(() =>
                                {
                                    rxPump.Run();
                                });

                                rxPump.FrameReceived += f => bc.Add(UnpackFrame(f));

                                rxRunner.Start();

                                for (int i = 0; i < 100; i++)
                                {
                                    txPump.Send(PackFrame(1));
                                    txPump.Send(PackFrame(8));
                                    txPump.Send(PackFrame(2));
                                    txPump.Send(PackFrame(7));
                                    txPump.Send(PackFrame(3));
                                    txPump.Send(PackFrame(6));
                                    txPump.Send(PackFrame(4));
                                    txPump.Send(PackFrame(5));

                                    Assert.IsTrue(SpinWait.SpinUntil(() => bc.Count == 8, 500));

                                    Assert.AreEqual(1, bc.Take());
                                    Assert.AreEqual(8, bc.Take());
                                    Assert.AreEqual(2, bc.Take());
                                    Assert.AreEqual(7, bc.Take());
                                    Assert.AreEqual(3, bc.Take());
                                    Assert.AreEqual(6, bc.Take());
                                    Assert.AreEqual(4, bc.Take());
                                    Assert.AreEqual(5, bc.Take());
                                }
                            }
                    }

            Assert.IsTrue(rxRunner.Join(500));
        }
        public void FramePumpDeferredProcessing()
        {
            int UnpackAndVerifyFrame(WireFrame frame, int expectedCount)
            {
                int count = frame.Segments.Count;

                Assert.AreEqual(expectedCount, count);

                for (int i = 0; i < count; i++)
                {
                    int length = frame.Segments[i].Length;
                    Assert.AreEqual(expectedCount - i, length);
                    for (int j = 0; j < length; j++)
                    {
                        Assert.AreEqual((ulong)(length - j), frame.Segments[i].Span[j]);
                    }
                }

                return(count);
            }

            WireFrame PackFrame(int value)
            {
                var segments = new Memory <ulong> [value];

                for (int i = 0; i < value; i++)
                {
                    ulong[] a = new ulong[value - i];
                    segments[i] = new Memory <ulong>(a);
                    for (int j = 0; j < a.Length; j++)
                    {
                        a[j] = (ulong)(a.Length - j);
                    }
                }

                return(new WireFrame(segments));
            }

            Thread rxRunner = null;

            using (var server = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.None))
                using (var client = new AnonymousPipeClientStream(PipeDirection.In, server.ClientSafePipeHandle))
                    using (var bc = new BlockingCollection <WireFrame>(8))
                    {
                        server.ReadMode = PipeTransmissionMode.Byte;
                        client.ReadMode = PipeTransmissionMode.Byte;

                        using (var txPump = new FramePump(server))
                            using (var rxPump = new FramePump(client))
                            {
                                rxRunner = new Thread(() =>
                                {
                                    rxPump.Run();
                                });

                                rxPump.FrameReceived += bc.Add;

                                rxRunner.Start();

                                txPump.Send(PackFrame(1));
                                txPump.Send(PackFrame(8));
                                txPump.Send(PackFrame(2));
                                txPump.Send(PackFrame(7));
                                txPump.Send(PackFrame(3));
                                txPump.Send(PackFrame(6));
                                txPump.Send(PackFrame(4));
                                txPump.Send(PackFrame(5));

                                Assert.IsTrue(SpinWait.SpinUntil(() => bc.Count == 8, 500));

                                UnpackAndVerifyFrame(bc.Take(), 1);
                                UnpackAndVerifyFrame(bc.Take(), 8);
                                UnpackAndVerifyFrame(bc.Take(), 2);
                                UnpackAndVerifyFrame(bc.Take(), 7);
                                UnpackAndVerifyFrame(bc.Take(), 3);
                                UnpackAndVerifyFrame(bc.Take(), 6);
                                UnpackAndVerifyFrame(bc.Take(), 4);
                                UnpackAndVerifyFrame(bc.Take(), 5);
                            }
                    }

            Assert.IsTrue(rxRunner.Join(500));
        }