On Thursday, October 5, 2023 at 12:10:37 AM UTC-7 Razvan Simerea wrote:

> In the Microsoft docs on gRPC interceptors for .NET it is said that:
>
> "gRPC server interceptors intercept incoming RPC requests. They provide
> access to the incoming request, the outgoing response, and the context for
> a server-side call."
>
> However, in the implementation, I couldn't find a method in the base
> interceptor for managing outgoing messages, but only incoming.
>
> Has anyone ever implemented an outgoing message server interceptor for
> .NET?

For unary and client streaming calls, you can access to the response message
by looking at the return of the continuation before you return from your
interceptor.

Here's a slight modification of the example UnaryServerHandler method in
ServerLoggerInterceptor.cs [0] that highlights where you can look at the
response message:

    public override async Task<TResponse> UnaryServerHandler<TRequest, 
TResponse>(
        TRequest request,
        ServerCallContext context,
        UnaryServerMethod<TRequest, TResponse> continuation)
    {
        LogCall<TRequest, TResponse>(MethodType.Unary, context);

        try
        {
            TResponse response = await continuation(request, context);
            // you have access to the response message here
            return response;
        }
        catch (Exception ex)
        {
            // Note: The gRPC framework also logs exceptions thrown by 
handlers to .NET Core logging.
            _logger.LogError(ex, $"Error thrown by {context.Method}.");


            throw;
        }
    }

For server streaming and duplex calls, your interceptor can pass its own
implementation of IServerStreamWriter to the continuation. Then, it will be
able to see the calls to WriteAsync to be able to inspect the messages. It
will also have to forward those on to the original IServerStreamWriter
implementation. For example (warning: email code, not tested):

public class ObservingServerStreamWriter<TResponse> : 
IServerStreamWriter<TResponse>
{
    private readonly IServerStreamWriter<TResponse> _inner;

    public 
ObservingServerStreamWriter(IServerStreamingWriter<IServerStreamWriter> 
inner)
    {
        _inner = inner;
        // capture whatever other state you need here
    }

    public WriteOptions? WriteOptions
    {
        get { return _inner.WriteOptions }
        set { _inner.WriteOptions = value; }
    }

    public Task WriteAsync<TResponse>(T message)
    {
        // you can observe message here
        return _inner.WriteAsync(message);
    }
}

--
Christopher Warrington
Microsoft Corp, but not on the gRPC team

[0]: 
https://github.com/grpc/grpc-dotnet/blob/207e8066f3ed2f6c656e565c07c746e282f54ff4/examples/Interceptor/Server/ServerLoggerInterceptor.cs#L33-L51

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to grpc-io+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/4edb4761-5112-4c1a-8824-64e059a187d4n%40googlegroups.com.

Reply via email to