asp.net-coregrpcconnection-refused

Getting Connection Refused After using gRPC client inside dockerize project in ASP.NET Core 8


I'm using ASP.NET Core 8 with gRpc. Inside Basket.API project which contains gRpc client, I'm calling one of the gRpc methods which is GetDiscountAsync:

    public async Task<CouponModel> GetDiscount(string productName)
    {
        var discountRequest = new GetDiscountRequest { ProductName = productName };
        return await _discountProtoService.GetDiscountAsync(discountRequest);
    }

The gRpc server proto file is inside Discount.Grpc project looks like this:

syntax = "proto3";

service DiscountProtoService {
    rpc GetDiscount (GetDiscountRequest) returns (CouponModel);
}

message GetDiscountRequest {
    string productName = 1; 
}

The problem is when I'm calling the GetDiscountAsync method inside basket project, I get an error: "Connection refused".

Grpc.Core.RpcException: Status(StatusCode="Unavailable", Detail="Error connecting to subchannel.", DebugException="System.Net.Sockets.SocketException (111): Connection refused
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
removed for clarity...

Here is the content of my docker-compose.override.yml file

basket.api:
    container_name: basket.api
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - "GrpcSettings:DiscountUrl=http://discount.grpc"
    ports:
      - "8001:8080"

  discount.grpc:
    container_name: discount.grpc
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - "DatabaseSettings:ConnectionString=Server=discountdb;Port=5432;Database=DiscountDb;User Id=admin;Password=***;"
    ports:
      - "8003:8080"

inside discount.grpc docker file

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8003

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["Services/Discount/Discount.Grpc/Discount.Grpc.csproj", "Services/Discount/Discount.Grpc/"]
RUN dotnet restore "./Services/Discount/Discount.Grpc/./Discount.Grpc.csproj"
COPY . .
WORKDIR "/src/Services/Discount/Discount.Grpc"
RUN dotnet build "./Discount.Grpc.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./Discount.Grpc.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Discount.Grpc.dll"]

gRPC appsetting

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    }
  }
}

I use following the following command for creating the application container:

docker-compose -f .\docker-compose.yml -f .\docker-compose.override.yml up

I tried several different ways to access the discount gRpc service but I couldn't.

Thanks in advance


Solution

  • Inside Basket.API i've changed the gRPC Client setting and it just works as expected.

    Inside appsetting of Basket.API

    "GrpcSettings": { "DiscountUrl": "http://host.docker.internal:8003" },

    Inside Programs.cs of Baskpet.API

    builder.Services.AddGrpcClient<DiscountProtoService.DiscountProtoServiceClient>
               (o => o.Address = new Uri(builder.Configuration["GrpcSettings:DiscountUrl"]
                                        ?? throw new Exception("Configration Not found")));
    

    I have to note that the port of gRPC server project is 8003 and instead of using localhost i have used host.docker.internal.