MobileBlazorBindings
MobileBlazorBindings copied to clipboard
[Request] Add samples with calls to gRPC and a Web API
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?
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
@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
- 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)
-
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
}
}
}
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
});
Thank you @Slevya for sharing!