Open ogauthier opened 4 years ago
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:
@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):
(Source: https://docs.microsoft.com/en-us/aspnet/core/grpc/browser?view=aspnetcore-5.0#grpc-web-and-streaming)
Grpc (gRPC methods):
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)
Anrdoid project:
add package -> Grpc.Core (2.32.0)
Works perfectly
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
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
});
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
}
}
}
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
});
Thank you @Slevya for sharing!
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?