Chat menjadi salah satu fitur yang wajib ada pada banyak aplikasi modern saat ini. Entah itu website toko daring, aplikasi edukasi, atau platform komunitas—semua membutuhkan interaksi real-time agar pengguna merasa lebih terlibat. Pada artikel kali ini, saya akan membahas studi kasus sederhana: bagaimana merancang dan mengimplementasikan sistem chat streaming menggunakan teknologi gRPC Streaming yang populer di lingkungan backend modern.
Studi Kasus: Persyaratan & Arsitektur
Persyaratan Fitur
- Pengguna dapat mengirim pesan chat.
- Semua pengguna yang terhubung dapat menerima pesan chat terbaru secara real-time.
- Setiap pengguna dapat melihat histori sesi chat ketika mereka masuk.
- Sistem cukup sederhana untuk dijalankan secara lokal.
- Toleransi sederhana terhadap multiple client.
Diagram Arsitektur
flowchart TD Client1 -->|Bidirectional Streaming| gRPCServer Client2 -->|Bidirectional Streaming| gRPCServer gRPCServer -->|Store Chat| DB[(Database)]
- Klien membuka koneksi bidirectional streaming dengan server gRPC.
- Ketika pesan dikirim, server menyimpannya ke database (atau memori), lalu melemparkannya ke semua klien aktif.
1. Persiapan: Stack Teknologi
- Bahasa: Go
- gRPC Framework:
google.golang.org/grpc
- Protobuf Compiler:
protoc
- Database: In-memory (slice/array) atau SQLite/Redis (opsional untuk persistensi)
2. Definisi Protobuf
chat.proto
syntax = "proto3";
package chat;
message ChatMessage {
string username = 1;
string message = 2;
string timestamp = 3;
}
service ChatService {
rpc ChatStream(stream ChatMessage) returns (stream ChatMessage);
}
3. Implementasi Server gRPC di Go
package main
import (
"context"
"fmt"
"log"
"net"
"sync"
"time"
pb "yourmodule/chat"
"google.golang.org/grpc"
)
type chatServer struct {
pb.UnimplementedChatServiceServer
mu sync.Mutex
clients map[string]pb.ChatService_ChatStreamServer
msgs []pb.ChatMessage
}
func (s *chatServer) ChatStream(stream pb.ChatService_ChatStreamServer) error {
id := fmt.Sprintf("client-%d", time.Now().UnixNano())
s.mu.Lock()
s.clients[id] = stream
for _, msg := range s.msgs {
stream.Send(&msg)
}
s.mu.Unlock()
defer func() {
s.mu.Lock()
delete(s.clients, id)
s.mu.Unlock()
}()
for {
msg, err := stream.Recv()
if err != nil {
log.Printf("client %s disconnected", id)
return err
}
msg.Timestamp = time.Now().Format(time.RFC3339)
s.mu.Lock()
s.msgs = append(s.msgs, *msg)
for _, c := range s.clients {
if err := c.Send(msg); err != nil {
log.Println("send error:", err)
}
}
s.mu.Unlock()
}
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
server := grpc.NewServer()
pb.RegisterChatServiceServer(server, &chatServer{
clients: make(map[string]pb.ChatService_ChatStreamServer),
})
log.Println("gRPC chat server started on :50051")
server.Serve(lis)
}
4. Simulasi Client gRPC
package main
import (
"context"
"fmt"
"log"
"time"
pb "yourmodule/chat"
"google.golang.org/grpc"
)
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
log.Fatalf("fail connect: %v", err)
}
defer conn.Close()
client := pb.NewChatServiceClient(conn)
stream, err := client.ChatStream(context.Background())
if err != nil {
log.Fatalf("fail stream: %v", err)
}
// Receive stream
go func() {
for {
msg, err := stream.Recv()
if err != nil {
log.Fatal(err)
}
fmt.Printf("[%s] %s: %s\n", msg.Timestamp, msg.Username, msg.Message)
}
}()
// Send messages
for {
var text string
fmt.Print("> ")
fmt.Scanln(&text)
stream.Send(&pb.ChatMessage{
Username: "ihsan",
Message: text,
})
}
}
5. Tabel Komponen dan Fungsinya
Komponen | Fungsi |
---|---|
ChatService.ChatStream | Endpoint utama gRPC untuk bidirectional streaming chat |
ChatMessage | Struktur data pesan yang dikirim dan diterima |
map[string]stream | Daftar koneksi klien aktif untuk broadcast |
[]ChatMessage | Riwayat chat untuk dikirim ulang saat klien terhubung |
6. Diagram Sekuensial Proses
sequenceDiagram participant Client as Klien participant Server as gRPC Server Client->>Server: Buka Stream Server-->>Client: Kirim histori pesan loop Chat Client->>Server: Kirim ChatMessage Server->>Server: Simpan pesan Server->>Client: Broadcast ke semua klien end
7. Kesimpulan
Dengan memanfaatkan gRPC bidirectional streaming, kita bisa membangun sistem chat real-time yang ringan, cepat, dan efisien untuk banyak klien. Pendekatan ini cocok untuk berbagai kebutuhan backend modern mulai dari fitur live support hingga aplikasi kolaborasi.
Untuk pengembangan lebih lanjut, Anda bisa menambahkan autentikasi, menyimpan pesan ke database sungguhan, atau mengintegrasikan sistem pub/sub seperti Redis agar bisa dijalankan secara horizontal.
Selamat mencoba dan semoga bermanfaat! 🚀
6 Inisialisasi Proyek Go untuk GraphQL
Artikel Terhangat
28 Studi Kasus: Streaming Chat Sederhana
07 Jul 2025
6 Inisialisasi Proyek Go untuk GraphQL
07 Jul 2025
4 Arsitektur GraphQL Server dalam Go
07 Jul 2025
25 Cara Mengontrol Aliran Data dengan Stream
07 Jul 2025

28 Studi Kasus: Streaming Chat Sederhana

6 Inisialisasi Proyek Go untuk GraphQL

4 Arsitektur GraphQL Server dalam Go
