Streaming Klien & Dua Arah
Bangun kanal streaming klien dan streaming dua arah full-duplex untuk skenario dengan throughput tinggi.
Streaming Klien & Dua Arah adalah pelajaran C# Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar C# Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus C# Academy mencakup 4 pelajaran total.
Streaming dari Klien dan Streaming Dua Arah
Selain RPC satu arah dan streaming dari server, gRPC mendukung streaming dari klien (klien mengirim banyak pesan, server merespons sekali) dan streaming dua arah (kedua sisi mengirim beberapa pesan secara bersamaan melalui satu koneksi).
Streaming dari Klien: Definisi Proto
Tambahkan kata kunci stream sebelum tipe permintaan. Klien mengirim rangkaian pesan, dan setelah selesai, server mengembalikan satu respons.
service UploadService {
// Client streams chunks, server returns a summary
rpc UploadFile (stream FileChunk) returns (UploadSummary);
}
message FileChunk { bytes data = 1; string filename = 2; }
message UploadSummary { int64 bytes_received = 1; string checksum = 2; }Menerapkan Streaming dari Klien di Server
Gunakan IAsyncStreamReader<T> untuk membaca pesan klien saat tiba. Panggil MoveNext() atau lakukan iterasi dengan ReadAllAsync().
public override async Task<UploadSummary> UploadFile(
IAsyncStreamReader<FileChunk> requestStream,
ServerCallContext context)
{
long totalBytes = 0;
using var ms = new MemoryStream();
await foreach (var chunk in requestStream.ReadAllAsync(context.CancellationToken))
{
await ms.WriteAsync(chunk.Data.Memory, context.CancellationToken);
totalBytes += chunk.Data.Length;
}
var checksum = ComputeMd5(ms.ToArray());
return new UploadSummary { BytesReceived = totalBytes, Checksum = checksum };
}Memanggil Streaming dari Klien pada Klien
Buka panggilan streaming, tulis pesan dengan RequestStream.WriteAsync(), lalu tandai penyelesaian dengan CompleteAsync(). Tunggu responsnya.
using var call = client.UploadFile();
var fileBytes = await File.ReadAllBytesAsync("large-file.bin");
const int chunkSize = 64 * 1024; // 64 KB
for (int offset = 0; offset < fileBytes.Length; offset += chunkSize)
{
var chunk = fileBytes.Skip(offset).Take(chunkSize).ToArray();
await call.RequestStream.WriteAsync(new FileChunk
{
Filename = "large-file.bin",
Data = Google.Protobuf.ByteString.CopyFrom(chunk)
});
}
await call.RequestStream.CompleteAsync(); // signal end
var summary = await call; // await server response
Console.WriteLine($"Uploaded {summary.BytesReceived} bytes");Streaming Dua Arah: Definisi Proto
Tambahkan stream di kedua sisi untuk komunikasi dupleks penuh. Klien dan server dapat mengirim pesan kapan saja secara terpisah.
service ChatService {
rpc Chat (stream ChatMessage) returns (stream ChatMessage);
}
message ChatMessage {
string user = 1;
string content = 2;
int64 sent_at = 3;
}Menerapkan Streaming Dua Arah di Server
Baca dari IAsyncStreamReader dan tulis ke IServerStreamWriter secara bersamaan. Gunakan Task.WhenAll untuk menjalankan kedua loop secara serentak.
public override async Task Chat(
IAsyncStreamReader<ChatMessage> requestStream,
IServerStreamWriter<ChatMessage> responseStream,
ServerCallContext context)
{
// Broadcast to all connected clients
var readTask = Task.Run(async () =>
{
await foreach (var msg in requestStream.ReadAllAsync(context.CancellationToken))
{
_chatHub.Broadcast(msg);
}
});
var writeTask = Task.Run(async () =>
{
await foreach (var msg in _chatHub.GetMessagesAsync(context.CancellationToken))
{
await responseStream.WriteAsync(msg);
}
});
await Task.WhenAll(readTask, writeTask);
}Streaming Dua Arah dari Klien
Kirim dan terima secara bersamaan dengan menjalankan dua tugas — satu untuk menulis pesan dan satu untuk membaca balasan.
using var call = client.Chat();
// Read task
var readTask = Task.Run(async () =>
{
await foreach (var msg in call.ResponseStream.ReadAllAsync())
Console.WriteLine($"{msg.User}: {msg.Content}");
});
// Write task
while (Console.ReadLine() is string text && text != "exit")
{
await call.RequestStream.WriteAsync(
new ChatMessage { User = "Alice", Content = text,
SentAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() });
}
await call.RequestStream.CompleteAsync();
await readTask;Kontrol Aliran dan Tekanan Balik
HTTP/2 memiliki kontrol aliran bawaan. Jika penerima lambat, gRPC otomatis menjeda pengirim sehingga mencegah memori meluap. Jangan menyangga pesan secara manual; biarkan aliran menanganinya.
// DO: Let gRPC flow control handle backpressure
await foreach (var chunk in requestStream.ReadAllAsync(ct))
{
await ProcessChunkAsync(chunk); // naturally paced
}
// DON'T: Buffering all chunks defeats flow control
var allChunks = new List<FileChunk>();
await foreach (var chunk in requestStream.ReadAllAsync(ct))
allChunks.Add(chunk); // may OOM on large uploadsPenutupan Separuh dan Penyelesaian Aliran
Dalam streaming dua arah, salah satu sisi dapat menutup bagian penulisannya sementara tetap membaca dari sisi lain. Hal ini memungkinkan klien memberi sinyal "selesai mengirim" sambil tetap menunggu respons server.
// Client signals it's done sending
await call.RequestStream.CompleteAsync(); // half-close
// Continue reading server responses after half-close
await foreach (var reply in call.ResponseStream.ReadAllAsync())
{
Console.WriteLine(reply.Content);
}Menggunakan Saluran untuk Streaming Dua Arah yang Aman bagi Utas
Gabungkan System.Threading.Channels dengan streaming dua arah untuk pola produsen-konsumen yang rapi dan menyalurkan pesan dengan aman ke banyak pendengar.
private readonly Channel<ChatMessage> _broadcast =
Channel.CreateUnbounded<ChatMessage>();
// Producer: receives from each client stream
public async Task ReceiveLoopAsync(
IAsyncStreamReader<ChatMessage> reader, CancellationToken ct)
{
await foreach (var msg in reader.ReadAllAsync(ct))
await _broadcast.Writer.WriteAsync(msg, ct);
}
// Consumer: writes to each client's response stream
public async Task SendLoopAsync(
IServerStreamWriter<ChatMessage> writer, CancellationToken ct)
{
await foreach (var msg in _broadcast.Reader.ReadAllAsync(ct))
await writer.WriteAsync(msg);
}Dunia Nyata: Alur Analitik Waktu Nyata
Layanan penyerapan data menerima aliran peristiwa telemetri dari perangkat IoT dan mengalirkan kembali statistik teragregasi secara waktu nyata — contoh penggunaan streaming dua arah yang sempurna.
service TelemetryService {
rpc StreamTelemetry(stream TelemetryEvent) returns (stream AggregatedStats);
}
// Server implementation sends a rolling aggregate every 100 events:
public override async Task StreamTelemetry(
IAsyncStreamReader<TelemetryEvent> requests,
IServerStreamWriter<AggregatedStats> responses,
ServerCallContext context)
{
int count = 0;
double total = 0;
await foreach (var e in requests.ReadAllAsync(context.CancellationToken))
{
total += e.Value;
if (++count % 100 == 0)
await responses.WriteAsync(
new AggregatedStats { Count = count, Average = total / count });
}
}Pemeriksaan Singkat
Dalam streaming dari klien, kapan server mengirim satu-satunya responsnya?
Ringkasan: Streaming dari Klien dan Streaming Dua Arah
Poin penting:
- Streaming dari klien: klien mengirim banyak pesan, server mengirim satu balasan — ideal untuk pengunggahan berkas
- Streaming dua arah: kedua sisi mengirim secara terpisah — ideal untuk obrolan dan umpan data langsung
- Gunakan
ReadAllAsync()untuk menerima aliran denganawait foreach - Panggil
RequestStream.CompleteAsync()untuk menutup separuh sisi penulisan klien - Kontrol aliran HTTP/2 menangani tekanan balik secara otomatis — jangan menyangga seluruh aliran
- System.Threading.Channels cocok dipadukan dengan streaming dua arah untuk skenario distribusi ke banyak penerima
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Streaming Klien & Dua Arah” gratis?
Ya — teks lengkap “Streaming Klien & Dua Arah” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus C# Academy, upgrade ke CoddyKit PRO. Kursus C# Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Streaming Klien & Dua Arah”?
Bangun kanal streaming klien dan streaming dua arah full-duplex untuk skenario dengan throughput tinggi. Kamu berlatih C# Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai C# Academy?
Tidak diperlukan pengalaman sebelumnya. C# Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Streaming Klien & Dua Arah” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran C# Academy ini?
Ya. Setiap pelajaran C# Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Dasar-Dasar gRPC & Protobuf
- RPC Unary & Streaming Server
- Streaming Klien & Dua Arah
- Batas Waktu, Pembatalan & Interceptor