DEV Community

Cover image for WTF is Grpc? Part 3: Real time Chat ft. Flutter and Golang
Md. Mobin
Md. Mobin

Posted on

WTF is Grpc? Part 3: Real time Chat ft. Flutter and Golang

Welcome back, dear readers, to the world of "Wtf is gRPC?" – where we turn tech into a comedy show! 🚀

In Part 3, we're diving into real-time chat with the grace of caffeine-fueled squirrels and the humor of rubber chickens at a stand-up gig!

Get ready to leave slow chats in the dust and make your app as snappy as a squirrel on roller skates. Grab your code editor, sense of humor, and let's chat it up in style. Part 3 is gonna be chat-tastic! 🍰💬😄

grpc-socket-meme

Table of Contents: Part 3 - Real-Time Chat Extravaganza 🎉

Introduction to gRPC Bi-directional: The Magic of Two-Way Chats

As we've journeyed through gRPC, we first delved into unary communication, which is essentially one-way communication from the client to the server. Then, we ventured into the world of server-side streaming.

Now, let's dive into gRPC Bi-directional communication. This is where things get really interesting! In Bi-directional streaming RPC, both the client and server engage in a lively conversation by sending a continuous stream of messages back and forth.

Here's how it works:

  • The client initiates the action by setting up an HTTP stream with some initial header frames.
  • Once this connection is established, both the client and the server can send messages simultaneously, without waiting for the other party to finish. It's like a dynamic chat where no one has to take turns.

Think of gRPC as the superhero chat line. It's like Tony's suit and Bruce's lab assistant, J.A.R.V.I.S., having a direct line to each other.

Socket vs. gRPC Bi-directional: A Cinematic Showdown" 🍿🎥

Aspect Socket gRPC Bi-directional Top-Rated Movie Comparison
Setup Complexity Generally low, traditional sockets require less setup Requires setting up gRPC services and protocols, which can be more complex Like the simplicity of "The Shawshank Redemption"
Communication Type Low-level and can be used for any data format High-level, designed for structured data transmission Similar to the plot intricacies of "The Godfather"
Performance Can be efficient for simple data exchange Optimized for high-performance, especially in microservices Like the action-packed "Mad Max: Fury Road"
Bi-directional Possible with added complexity and custom handling Inherently supports efficient bi-directional communication Much like "Pulp Fiction's" non-linear storytelling
Error Handling Requires custom error handling Provides built-in status codes and error handling Comparable to the suspense in "The Silence of the Lambs"
Cross-Language Supports multiple programming languages Multi-language support with protocol buffers Like the multilingual charm of "Inglourious Basterds"
Integration Ease Requires more manual integration Easier integration into gRPC-compatible systems Much like the seamless blend in "The Dark Knight"

grpc bi-directional

Setup Your Server: Where the Real-Time Chat Spells Begin

  • Let's continue code from part 2,where we left.
git clone git@github.com:Djsmk123/Wtf-is-grpc.git
Enter fullscreen mode Exit fullscreen mode
  • Switch to part-2 branch(for starter code)
git switch part2
Enter fullscreen mode Exit fullscreen mode
  • As we are going to create Chat one to one service for that we required to get all the users and then communicate.

  • Create profobuf for getting users(rpc_users.proto)

  • Add GetUsers rpc service in GRPCServerService
// add this line to import
import "rpc_users.proto";

service GrpcServerService {
// add this line too
    rpc GetUsers(UsersListRequest) returns (ListUserMessage) {};
}
Enter fullscreen mode Exit fullscreen mode
  • Generate equivalent code for server(Golang)
protoc --proto_path=proto --go_out=pb --go_opt=paths=source_relative \
    --go-grpc_out=pb --go-grpc_opt=paths=source_relative \
    proto/*.proto
Enter fullscreen mode Exit fullscreen mode
  • Add function in auth package get_users.go
  • Let's call this function in grpc-server interface(package gapi) and add this function in auth.go.
  • We are done with this. But we required users so that we can send message so don't, I am providing list of users (around 35), just load them into mongodb.

users-data.json

Note: Password for each user is 12345678.

Setting Up Your Chat Service:

Establishing a chat service is a straightforward procedure.

  • RPC Service Creation : Creating an RPC (Remote Procedure Call) service is at the core of this setup.
  • Bidirectional Message Stream: Implement a bidirectional stream of messages.Messages are initiated by the client and sent to the server.
  • Bidirectional Response Stream: Create a bidirectional stream for responses.Responses are generated by the server and sent back to the client.
  • Acknowledgment Mechanism: Before actual communication begins, an acknowledgment mechanism is necessary to connect both the client and the server.This mechanism helps ensure a successful connection.
  • Database Handling: Notably, the acknowledgment message is designed to be transient and is not stored in the database.
  • Confirmation of Connection: The acknowledgment message serves as a confirmation of a successful connection.

  • Setting up protos: Setup proto for Sending message and get messages

  • Add these rpc function into service
service GrpcServerService {
//add these lines
    rpc SendMessage(stream SendMessageRequest) returns (stream Message){};
    rpc GetAllMessage(GetAllMessagesRequest) returns (GetAllMessagesResponse){};
}
Enter fullscreen mode Exit fullscreen mode
  • Generate equivalent code
protoc --proto_path=proto --go_out=pb --go_opt=paths=source_relative \
    --go-grpc_out=pb --go-grpc_opt=paths=source_relative \
    proto/*.proto
Enter fullscreen mode Exit fullscreen mode
  • We need JWT-based authentication for both receiving and sending messages. While there are two types of interceptors available, namely unary interceptors and stream interceptors, we currently utilize the unary interceptor as our middleware and lets add middleware for stream service too.

user-auth

  • update middleware.go in gapi package.
  • Register middleware in main.go
//update this line
grpcServer := grpc.NewServer(
        grpc.UnaryInterceptor(server.UnaryAuthInterceptor),
        grpc.StreamInterceptor(server.StreamAuthInterceptor),
    )
Enter fullscreen mode Exit fullscreen mode
  • Now create Message Object for mongodb collection
  • Update MongoCollection
type MongoCollections struct {
    Users *mongo.Collection
    Chats *mongo.Collection
}
Enter fullscreen mode Exit fullscreen mode
  • Before going to into complex part to listen message and store them into db, lets deal with simple rpc function GetAllMessage from db and SendMessage to store the message.
  • Now we are going to use go-routine to listen and send message to the client

We are using goroutines and channels to listen for changes in the database. If you want to learn more about goroutines, you can read this blog

  • Let's Define SendMessage and GetAllMesasge for grpc server interface.

Note: To make connection b/w two users, its required to send first message Join_room so that other user can get acknowledgment.

Testing gRPC in CLI

grpc-testing

Start with Flutter Application: Embark on Your Chatting Adventure

  • Add following dependency into your project:
flutter pub add intl
Enter fullscreen mode Exit fullscreen mode
  • Generate equivalent code for dart from protos.
protoc --proto_path=proto --dart_out=grpc:lib/pb proto/*.proto
Enter fullscreen mode Exit fullscreen mode
  • As it is known issue dart does not generate code google/protobuf/timestamp.pb.dart,read here. So download this file google_timestamp.pb.dart and update the generated code as required(just change import path)

  • Before starting chat service we need to display all the users into home screen so that we can send message to other users

PS: I am not going to talk about basic UI building for showing the list of users.

  • Add function to get all users in AuthService class
class AuthServices{
//keep same, add this function
  static Future<List<UserModel>> getUsers(
      {int pageNumber = 1, String? search}) async {
    final res = await GrpcService.client.getUsers(
        UsersListRequest(pageSize: 10, pageNumber: pageNumber, name: search),
        options: CallOptions(metadata: {'authorization': 'bearer $authToken'}));
    return res.users.map((e) => UserModel(e.id, e.username, e.name)).toList();
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Call this function in HomeScreen(),for reference use this ui or create your own.

  • Let's Create chat service to get messages(History)

class ChatService {
  static Future<List<Message>> getMessages(String username) async {
    final res = await GrpcService.client.getAllMessage(
        GetAllMessagesRequest(
          reciever: username,
        ),
        options: CallOptions(
            metadata: {'authorization': 'bearer ${AuthService.authToken}'}));
    return res.messages;
  }
}

Enter fullscreen mode Exit fullscreen mode
  • Let's listen for messages,send message and fetch history.

Note: UI component maybe missing or you create your own. for reference check source code

  • Let's talk about what we did in above class.
    • In initState() we are starting to listen message by sending first message Join_room to make connection and another function fetchChatsHistory() as name suggested, getting earlier messages by calling grpc unary service.
    • on sending message we are adding message data to stream-controller to send stream of message to the server.

Outputs: The Hilarious Messages of Success

End of the series

Thank you to everyone who has supported me throughout this series. I promise to be more consistent next time. The blog series titled 'Wtf is gRPC?' comes to an end with this post. In Part 1, we delved into authentication and authorization using unary gRPC communication. In Part 2, we had some fun creating a custom notification service in Flutter, along with server-side streaming gRPC. And now, in the grand finale, Part 3, we explored bi-directional gRPC to create a simple real-time chat application. Thanks again, and remember, gRPC isn't as mysterious as it sounds – it's just a protocol! Stay tuned for more tech adventures!

Thank for 2k+ Followers on dev.to

Thanks You

flutter meme

Source code :

Github Repo

Follow me on

Top comments (0)