Grpc Server - Server streaming RPC - Create a SignOn service to return list of users


Scenario:

Create a Sign on service to return list of users in out system. The web App calls this service to fetch list of users one by one and render on UI.

Solution:

Create Server streaming Grpc service for sign on in .Net core 3.0 with GetAllUsers method.

per gRPC documentation

A server-streaming RPC is similar to our simple example, except the server sends back a stream of responses after getting the client’s request message.The client completes once it has all the server’s responses.
  1. VS 2019 -> New Project -> gRPC Service -> GrpcServer
  2. Create Service definition [proto file], name signon.proto and define the service as below

  3. syntax = "proto3";
    
    option csharp_namespace = "GrpcServer";
    
    service SignOn {
        rpc GetAllUsers (UserRequest) returns (stream User);
    }
    
    message UserRequest {
    
    }
    
    message User {
      string email = 1;
      string name = 2;
    }
    

  4. Right click on the proto file and make sure below properties are correctly set

  5. gRPC Stub Class
    Server only
    
    Protobuf 
    Class access = Public

  6. Override GetAllUsers in SignOnService.cs 

  7. 
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    public override async Task GetAllUsers(UserRequest request, IServerStreamWriter<User> responseStream, ServerCallContext context)
            {
                var response = new SignOnResponse();
                response.Sucess = false;
    
                var json = JsonConvert.SerializeObject(request);
                var elasticSearch = new ElasticSearchService();
                var esResponse = elasticSearch.SearchData(json, "ELK:indexes:userIndex");
    
                var users = new List<User>();
    
                if (!string.IsNullOrWhiteSpace(esResponse))
                {
                    response.Sucess = true;
                    var rootHits = (JObject)JObject.Parse(esResponse)["hits"];
                    var hits = (JArray)rootHits["hits"];
    
                    for (int i = 0; i < hits.Count; i++)
                    {
                        if (hits[i]["_source"]["Email"] != null)
                        {
                            users.Add(new User
                            {
                                Email = hits[i]["_source"]["Email"] == null ? "" : hits[i]["_source"]["Email"].ToString(),
                                Name = hits[i]["_source"]["Name"] == null ? "" : hits[i]["_source"]["Name"].ToString(),
                            });
                        }
                    }
                }
    
                //return back to client one user at a time
                foreach (var user in users)
                {
                    await responseStream.WriteAsync(user);
                }
            }

  8. Create web project - VS 2019 -> New Project -> Web -> MyApp
  9. Add below nuget packages

  10. 1
    2
    3
    Google.Protobuff
    Grp.Net.Client
    Grpc.Tools
    

  11. Add Proto folder to project -> copy file signon.proto from server to here
  12. Invoke the service from client as below

  13.  1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public async Task<IActionResult> Index()
            {
                var users = new List<string>();
    var channel = GrpcChannel.ForAddress(grpServerUrl); var client = new SignOn.SignOnClient(channel);
                using (var call = client.GetAllUsers(new UserRequest()))
                {
                    while (await call.ResponseStream.MoveNext())
                    {
                        var user = call.ResponseStream.Current;
                        users.Add(user.Name);
                    }
                }
                ViewBag.success = true;
    
                return View();
            }

No comments:

Post a Comment

Move Github Sub Repository back to main repo

 -- delete .gitmodules git rm --cached MyProject/Core git commit -m 'Remove myproject_core submodule' rm -rf MyProject/Core git remo...