private async Task RunClientAsync(IDuplexPipe pipe, LightweightRpcEndPoint endPoint, IPrincipal?user)
        {
            var client = new ClientPipeline(pipe, this, endPoint, user, this.MaxRequestSize, this.MaxResponseSize, this.KeepSizeLimitedConnectionAlive);

            try
            {
                try
                {
                    this.AddClient(client);

                    await client.RunAsync().ContextFree();
                }
                finally
                {
                    await client.DisposeAsync().ContextFree();
                }
            }
            finally
            {
                // Late removal of client (after dispose and wait) to avoid that shut down returns
                // before all clients have ended. Make sure that a client is not accidentally used
                // after dispose.
                this.RemoveClient(client);
            }
        }
Exemplo n.º 2
0
 internal ClientPipeline(IDuplexPipe pipe, LightweightRpcServer server, LightweightRpcEndPoint endPoint, IPrincipal?user, int?maxRequestSize, int?maxResponseSize, bool skipLargeFrames)
     : base(pipe, maxResponseSize, maxRequestSize, skipLargeFrames)
 {
     this.server     = server;
     this.endPoint   = endPoint;
     this.user       = user;
     this.serializer = server.Serializer;
 }
        public void AddEndPoint(LightweightRpcEndPoint endPoint)
        {
            if (endPoint == null)
            {
                throw new ArgumentNullException(nameof(endPoint));
            }

            lock (this.SyncRoot)
            {
                this.CheckIsInitializing();
                this.endPoints.Add(endPoint);
            }

            this.ServicePublisher.TryInitConnectionInfo(endPoint.GetConnectionInfo(this.ServicePublisher.ServerId));
        }
 public Task RunPipelineClientAsync(IDuplexPipe clientPipe, LightweightRpcEndPoint endPoint, IPrincipal?user)
 => this.server.RunClientAsync(clientPipe, endPoint, user);
 public ValueTask <byte[]?> HandleDatagramAsync(LightweightRpcEndPoint endPoint, byte[] data, CancellationToken cancellationToken)
 => this.server.HandleDatagramAsync(endPoint, data, cancellationToken);
        private async ValueTask <byte[]?> HandleDatagramAsync(LightweightRpcEndPoint endPoint, byte[] data, CancellationToken cancellationToken)
        {
            if (LightweightRpcFrame.TryRead(data, this.MaxRequestSize, out var frame) == RpcFrameState.Full)
            {
                if (frame.FrameType != RpcFrameType.UnaryRequest)
                {
                    this.Logger.LogWarning("Datagram only handles unary requests.");
                    return(null);
                }

                var methodStub = this.GetMethodDefinition(frame.RpcOperation);
                if (methodStub == null)
                {
                    this.Logger.LogWarning("Unknown operation '{Operation}' in datagram frame.", frame.RpcOperation);
                    return(null);
                }

                CancellationToken       actualCancellationToken;
                CancellationTokenSource?timeoutCts = null;
                CancellationTokenSource?linkedCts  = null;
                if (frame.Timeout > 0)
                {
                    timeoutCts = new CancellationTokenSource();
                    timeoutCts.CancelAfter((int)frame.Timeout);
                    if (cancellationToken.CanBeCanceled)
                    {
                        linkedCts = CancellationTokenSource.CreateLinkedTokenSource(timeoutCts.Token, cancellationToken);
                        actualCancellationToken = linkedCts.Token;
                    }
                    else
                    {
                        actualCancellationToken = timeoutCts.Token;
                    }
                }
                else
                {
                    actualCancellationToken = cancellationToken;
                }

                try
                {
                    var context = new LightweightCallContext(endPoint, null, frame.Headers, actualCancellationToken);

                    using IServiceScope? scope = this.ServiceProvider?.CreateScope();
                    using var frameWriter      = new LightweightRpcFrameWriter(65536);
                    await methodStub.HandleMessage(frameWriter, frame, scope?.ServiceProvider, context).ContextFree();

                    return(frameWriter.GetFrameData());
                }
                catch (Exception x)
                {
                    this.Logger.LogWarning(x, "Error occurred in HandleDatagramAsync.");
                }
                finally
                {
                    linkedCts?.Dispose();
                    timeoutCts?.Dispose();
                }
            }
            else
            {
                this.Logger.LogInformation("Received incomplete datagram frame.");
            }

            return(null);
        }