In this post, we will address how to create a gRPC client in Flutter and connect to a Server. In order to test our client application, we will quickly build a gRPC service using .Net.
gRPC Server (C# .Net)
Let us use the Asp.Net core gRPC Service template provided by Visual Studio.

With the basic template in place, let us now go ahead and create our gRPC Protocol Buffers.
syntax = "proto3";
option csharp_namespace = "GrpcDemoServer";
package greet;
service Instrument{
rpc ReadStatus (ReadStatusRequest) returns (ReadStatusResponse);
}
message ReadStatusRequest {
int32 id = 1;
}
message ReadStatusResponse{
string status = 1;
}
As observed in the above definition, we have a single service, namely Instrument, which has a single RPC method exposed – ReadStatus. The method accepts a ReadStatusRequest
type as parameter and returns ReadStatusResponse
type.
The ReadStatusRequest
and ReadStatusResponse
is defined as the following.
message ReadStatusRequest {
int32 id = 1;
}
message ReadStatusResponse{
string status = 1;
}
We will now create the corresponding service in our C# project.
publicclassInstrumentService: Instrument.InstrumentBase
{
public override Task<ReadStatusResponse> ReadStatus(ReadStatusRequest request, ServerCallContext context)
{
return Task.FromResult(new ReadStatusResponse
{
Status = $"Connected : {TimeOnly.FromDateTime(DateTime.Now).ToLongTimeString()}"
}) ;
}
}
The key point to not here is that our InstrumentService
class inherits from the Instrument.InstrumentBase
class, which is the compiler generated code based on our protocol buffers defined earlier. The service itself doesn’t do much (to keep it simple for sake of example). It returns a string with the current TimeStamp
.
Notice the usage of new
TimeOnly
data type. This stores the Time only information, a good addition to the language, which was previously limited by the DateTime data type.
The final step towards completing our service involves mapping the incoming requests to the InstrumentService
. This can be done as the following.
app.MapGrpcService<InstrumentService>();
That is all we need to as far as our server is concerned. Before we proceed to the defining our client code, do not forget to look at your launchSetttings.json
to get the port number in which the service would be running at.
{"profiles":{"GrpcDemoServer":{"commandName":"Project","dotnetRunMessages":true,"launchBrowser":true,"applicationUrl":"http://localhost:5280;https://localhost:7280","environmentVariables":{"ASPNETCORE_ENVIRONMENT":"Development"}}}}
We can now proceed to develop our client in flutter.
gRPC Client (Flutter/Dart)
Before we begin writing code for our Flutter Client, we need to add the protocol buffers defined earlier in our server to the client. Once added, we need use the protoc compliler to the generate the associated dart definitions. For installing the Protoc compiler, please refer the official documentation here
protoc --dart_out=grpc:lib\generated -Iprotos protos\greet.proto
This would generate the following files
greet.pb.dart
greet.pbenum.dart
greet.pbgrpc.dart
greet.pbjson.dart
For the sake of example, we will keep the flutter code as simple as possible. We will need a button, which the Users can use to request the client to connect and invoke the method exposed in the server.
floatingActionButton: FloatingActionButton(
onPressed: sendRequest,
tooltip: 'Send Request',
child: const Icon(Icons.arrow_forward),
)
The next obvious step is to define the sendRequest
method which would send the actual request to the server. We would need to import the grpc.dart
package for the purpose.
import'package:grpc/grpc.dart';
Also ensure it is added in the dependencies
list in pubsec.yaml
.
dependencies:flutter:sdk:fluttergrpc:^3.0.2
With that in place, let us now define out sendRequest
method.
var _message = "";
late InstrumentClient stub;
Future<void> sendRequest() async {
final channel = ClientChannel('localhost',
port: 5280,
options:
const ChannelOptions(credentials: ChannelCredentials.insecure()));
stub = InstrumentClient(channel,
options: CallOptions(timeout: constDuration(seconds: 30)));
try {
var readRequest = ReadStatusRequest(id: 1);
var response = await stub.readStatus(readRequest);
setState(() {
_message = response.status;
});
} catch (e) {
setState(() {
_message = e.toString();
});
}
}
The method create a ClientChannel
instance on localhost
, which use the port 5280
(same as the one used by our server). It would then use the connect to our server using the InstrumentClient
class generated by protoc
compiler in the previous step. Do not forget to add the reference to the greet.pbgrpc.dart
.
import'package:democlient/src/generated/greet.pbgrpc.dart';
We then create an instanace of the ReadStatusRequest
data type and use the stub.ReadStatus
method to send the request.
var response = await stub.readStatus(readRequest);
That’s all we would require to connect to the gRPC server using flutter. The complete source code used in this example can be accessed from my github here.
2 thoughts on “Create a Flutter gRPC client”