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); } }
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); }