Dalam dunia microservices modern, gRPC telah menjadi salah satu pilihan utama untuk membangun komunikasi antar layanan yang efisien, terutama jika mengutamakan performa dan fleksibilitas. Salah satu fitur powerful dari gRPC adalah dukungan terhadap streaming RPC. Kali ini, mari kita fokus pada Client-side Streaming RPC, di mana klien dapat mengirimkan banyak pesan secara berurutan ke server, sebelum akhirnya menerima satu respon agregat dari server.
Artikel ini akan membahas konsep, skenario penggunaan, serta memberikan contoh implementasi Client-side Streaming RPC menggunakan Go (golang
). Untuk memperjelas, akan disertakan diagram flowchart dan simulasi komunikasi agar Anda mendapatkan gambaran lengkap terkait fitur ini.
Apa Itu Client-side Streaming RPC?
Pada Client-side Streaming RPC, alur komunikasinya kurang lebih seperti berikut:
- Klien membuka koneksi dan secara bertahap mengirimkan beberapa pesan ke server menggunakan stream.
- Setelah semua data dikirim, klien menutup stream.
- Server memproses semua data dan mengirimkan satu respon kembali ke klien.
Berbeda dengan Unary RPC (satu permintaan-satu jawaban) atau Server Streaming (satu permintaan-respon bertahap), di streaming client-side klien memegang kendali berapa banyak pesan yang dikirim sebelum meminta jawaban dari server.
Contoh Use Case
Use case | Deskripsi |
---|---|
Upload file bertahap | Klien mengirim bagian file satu per satu ke server |
Pengiriman batch data IoT | Device IoT mengirimkan data sensor bertahap ke server |
Client-side logging | Klien mengirimkan banyak pesan log lalu menerima summary |
Arsitektur dan Flow
Mari kita lihat diagram interaksinya dengan Mermaid:
sequenceDiagram participant Client participant Server Client->>Server: Buka stream loop Satu per satu Client->>Server: Kirim message (chunk data) end Client-->>Server: Tutup stream (Done) Server-->>Client: Kirim respon hasil agregasi
Pada dasarnya, streaming dimulai ketika klien membuka stream, mengirim semua pesan (bisa loop, misal saat user upload 10MB file dikirim chunk 512KB secara bertahap), lalu akhirnya closing stream dengan CloseAndRecv
. Server baru akan memproses setelah stream ditutup.
Skema Protobuf untuk Client-streaming
Misalkan kita ingin mengimplementasikan fitur upload file bertahap seperti Google Drive. Kita dapat mendefinisikan service gRPC di file upload.proto sebagai berikut:
syntax = "proto3";
service FileService {
// UploadFile: Client streaming, server hanya kirim satu hasil.
rpc UploadFile (stream Chunk) returns (UploadStatus);
}
message Chunk {
bytes content = 1;
}
message UploadStatus {
bool success = 1;
string message = 2;
}
Penjelasan:
- Chunk: Struktur pesan yang dikirim klien. Biasanya berisi bagian file (bytes).
- UploadStatus: Respon status akhir dari server.
Implementasi Client-side Streaming RPC
1. Implementasi Server (Go/gRPC)
Pada server, kita perlu meng-handle data secara bertahap sampai stream client ditutup, kemudian membalas dengan satu pesan.
// file_service.go
type FileServiceServer struct {
pb.UnimplementedFileServiceServer
}
func (s *FileServiceServer) UploadFile(stream pb.FileService_UploadFileServer) error {
fmt.Println("Start receiving file chunks...")
var totalBytes int64
for {
chunk, err := stream.Recv()
if err == io.EOF {
// Selesai, balas ke client
return stream.SendAndClose(&pb.UploadStatus{
Success: true,
Message: fmt.Sprintf("Upload selesai: %d bytes diterima.", totalBytes),
})
}
if err != nil {
return err
}
// Simulasi write ke disk
totalBytes += int64(len(chunk.Content))
}
}
Penjelasan:
stream.Recv()
: Mendapatkan setiap chunk dari klien.- Saat stream EOF (klien tutup stream), server membalas status upload.
2. Implementasi Client (Go/gRPC)
Sisi klien akan membuka stream lalu mengirimkan data secara bertahap.
func uploadFile(client pb.FileServiceClient, filePath string) {
ctx := context.Background()
stream, err := client.UploadFile(ctx)
if err != nil {
log.Fatalf("Gagal membuka stream: %v", err)
}
file, err := os.Open(filePath)
if err != nil {
log.Fatalf("Gagal buka file: %v", err)
}
defer file.Close()
buf := make([]byte, 512*1024) // Chunk 512KB
for {
n, err := file.Read(buf)
if n > 0 {
if err := stream.Send(&pb.Chunk{Content: buf[:n]}); err != nil {
log.Fatalf("Gagal kirim chunk: %v", err)
}
}
if err == io.EOF {
break
} else if err != nil {
log.Fatalf("Gagal baca file: %v", err)
}
}
status, err := stream.CloseAndRecv()
if err != nil {
log.Fatalf("Gagal menerima status upload: %v", err)
}
fmt.Printf("Server reply: %v\n", status.Message)
}
Simulasi Komunikasi
Mari kita simulasikan pengiriman file 2MB dalam potongan 512KB:
Urutan Chunk | Ukuran (KB) | Event di Server |
---|---|---|
1 | 512 | Menerima chunk 1 (akumulasi: 512KB) |
2 | 512 | Menerima chunk 2 (1MB) |
3 | 512 | Menerima chunk 3 (1.5MB) |
4 | 512 | Menerima chunk 4 (2MB) |
EOF | - | Stream tutup, kirim status |
Respons server:
“Upload selesai: 2097152 bytes diterima.”
Kapan Menggunakan Client-side Streaming?
Gunakan Client-side Streaming RPC ketika:
- Data dari klien besar/banyak & ingin menghindari satu payload raksasa.
- Data realtime yang ingin dikirim bertahap sebelum hasil agregasi diproses.
- Klien punya data dalam batch, misal update ribuan records sekaligus.
Perbandingan (Tabel)
Teknik | Cara Kerja | Kelebihan | Kekurangan |
---|---|---|---|
Unary RPC | Satu permintaan-respon | Simple, mudah di-implementasi | Payload terbatas |
Server streaming | Server kirim stream | Respon terus-menerus | Client hanya bisa kirim satu request |
Client streaming | Client kirim stream | Client bisa batching data | Agak kompleks |
Bi-directional | Dua arah stream | Full-duplex, sangat fleksibel | Komunikasi rumit |
Kesimpulan
Client-side Streaming RPC sangat bermanfaat untuk efisiensi komunikasi data skala besar atau batch tanpa membebani server atau jaringan dengan satu payload besar. Dengan dukungan protokol gRPC, implementasinya relatif sederhana dan scalable. Semoga artikel ini membantu Anda memahami dan mengimplementasikan pola ini!
Jika ingin diskusi lebih lanjut atau contoh di bahasa lain, silakan tinggalkan komentar!
Happy Streaming! 🚀
22 Implementasi Server-side Streaming RPC
Artikel Terhangat
23 Implementasi Client-side Streaming RPC
07 Jul 2025
22 Implementasi Server-side Streaming RPC
06 Jun 2025
21 Memahami Konsep Streaming pada gRPC
06 Jun 2025
20 Menambahkan Interceptor Unary di Client
06 Jun 2025
19 Menambahkan Interceptor Unary di Server
06 Jun 2025
18 Membaca Metadata di Server gRPC
06 Jun 2025
17 Menambahkan Metadata pada gRPC Request
06 Jun 2025

23 Implementasi Client-side Streaming RPC

22 Implementasi Server-side Streaming RPC

21 Memahami Konsep Streaming pada gRPC

20 Menambahkan Interceptor Unary di Client

19 Menambahkan Interceptor Unary di Server

18 Membaca Metadata di Server gRPC
