MobileBlazorBindings icon indicating copy to clipboard operation
MobileBlazorBindings copied to clipboard

[Request] Add samples with calls to gRPC and a Web API

Open ogauthier opened this issue 5 years ago • 3 comments
trafficstars

I'm trying to make a sample application that communicates with gRPC Server with the new GprcWeb package and can't make it to work on my Android simulator. I also failed to make a call with HttpClient. Can you add new samples that could show how?

ogauthier avatar Mar 10 '20 18:03 ogauthier

This is a great suggestion, I will look into it.

In the meantime anything you find regarding gRPC in Xamarin.Forms should work the same in Mobile Blazor Bindings, aside from the UI part. I found some threads here that talk about it in general:

  • Using gRPC in Xamarin.Forms: https://github.com/grpc/grpc/issues/16250, including special notes about adding references
  • And this ultimately links to this sample (which I haven't evaluated): https://github.com/grpc/grpc/tree/master/examples/csharp/HelloworldXamarin

Eilon avatar Mar 10 '20 18:03 Eilon

@ogauthier @Eilon GRPC working as well on MBB (we are using Hybrid templates)

You can directly use Grpc (HttpProtocols.Http2) for fast communications, instead of GrpcWeb, which using http1 protocol

Benefits here: (https://factoryhr.medium.com/http-2-the-difference-between-http-1-1-benefits-and-how-to-use-it-38094fa0e95b)

Benefits of Grpc, instead of GrpcWeb:

GrpcWeb (gRPC methods):

  • Unary
  • Server streaming

(Source: https://docs.microsoft.com/en-us/aspnet/core/grpc/browser?view=aspnetcore-5.0#grpc-web-and-streaming)

Grpc (gRPC methods):

  • Unary
  • Server streaming
  • Client streaming
  • Bi-directional streaming

(Source: https://docs.microsoft.com/en-us/aspnet/core/grpc/services?view=aspnetcore-5.0#implement-grpc-methods)


On Xamarin client

  1. Share project: add packages -> Google.Protobuf (3.15.3), Gprc.Core(2.32.0), Gprc.Tools(2.32.0)

Why Grpc.Core is 2.32.0? cause upper versions have many problems with linking in iOS

How to solve it? Here: (source: https://techblog.livongo.com/fixing-grpc-xamarin-ios-linking-errors) and here: https://github.com/grpc/grpc/issues/19172#issuecomment-730364709

add @using Grpc.Core in your _Imports.razor
add Protos (enough on share project)
  1. Anrdoid project: add package -> Grpc.Core (2.32.0) Works perfectly

  2. iOS project: add package -> Grpc.Core (2.32.0)

add to your ios csproj ->

<Target Name="GrpcCoreShim" BeforeTargets="CoreCompile">
    <PropertyGroup>
      <GrpcCoreTargetsRelativePath>..\..\..\.nuget\packages\grpc.core\2.32.0</GrpcCoreTargetsRelativePath>
    </PropertyGroup>
    <ConvertToAbsolutePath Paths="$(GrpcCoreTargetsRelativePath)">
      <Output TaskParameter="AbsolutePaths" PropertyName="GrpcCoreTargetsAbsPath" />
    </ConvertToAbsolutePath>
    <ItemGroup>
      <NativeReference Remove="libgrpc_csharp_ext.a" />
      <NativeReference Remove="libgrpc.a" />
      <NativeReference Include="$(GrpcCoreTargetsAbsPath)\native\ios\universal\libgrpc_csharp_ext.a">
        <Kind>Static</Kind>
        <ForceLoad>True</ForceLoad>
        <IsCxx>True</IsCxx>
      </NativeReference>
      <NativeReference Include="$(GrpcCoreTargetsAbsPath)\native\ios\universal\libgrpc.a">
        <Kind>Static</Kind>
        <ForceLoad>True</ForceLoad>
        <IsCxx>True</IsCxx>
      </NativeReference>
    </ItemGroup>
  </Target>

Attention: The amount of ..\ in < GrpcCoreTargetsRelativePath> is individual...

Tested on Simulator (Iphone 11 14.4), and real device Iphone Xr (14.4) Works perfectly

  1. If you are using hybrid template, then you can add Grpc Channel like singleton in dependency services in App.cs
 services.AddSingleton(services =>
                    {
                        AppContext.SetSwitch(
               "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); //use if unencrypted connection 
                        return new Channel("server_ip:5001", ChannelCredentials.Insecure); // if localhost = "127.0.0.1:5001" //ChannelCredentials.Insecure - if unencrypted connection
                    });
  1. Inject Grpc channel on blazor views like ->
@code {
    [Inject]
    Channel grpcChannel { get; set; }

    protected override async Task OnInitializedAsync()
    {
        var client = new YourProtoService.YourProtoClient(grpcChannel);
        try
        {
            var reply = await client.YourProtoRpc(new YourProtoRequest);
            //TODO some work with reply
        }
        catch (RpcException rpc)
        {
            //TODO catch when rpc exceptions, e.g Unauthenticated or smthng
        }
        catch (Exception e)
        {
            //TODO catch when others exceptions
        }
    }
}

On Server

You can use GrpcService template (one of asp net core templates) In Program.cs

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    webBuilder.UseKestrel(options =>
                    {
                        options.Listen(IPAddress.Loopback, port: 4099); //for localhost
                        options.Listen(IPAddress.Any, port: 5001, listenOptions =>
                        {
                            listenOptions.Protocols = HttpProtocols.Http2;
                        });                      
                    });
                });

In middleware (Startup.cs, method Configure)

  app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
               //add other endpoints like asp net core mvc, api
                endpoints.MapGrpcService<YourService>(); //.EnableGrpcWeb() - for grpc web
            });

Slevya avatar Mar 18 '21 11:03 Slevya

Thank you @Slevya for sharing!

Eilon avatar Mar 30 '21 18:03 Eilon