Penstriman Klien & Dwiarah
Bina saluran penstriman klien dan penstriman dwiarah dupleks penuh untuk senario daya pemprosesan tinggi.
Penstriman Klien & Dwiarah ialah pelajaran Akademi C# percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Akademi C#, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Akademi C# merangkumi sejumlah 4 pelajaran.
Penstriman Client dan Penstriman Dua Hala
Selain RPC tunggal dan penstriman pelayan, gRPC menyokong penstriman client (client menghantar banyak mesej, pelayan membalas sekali) dan penstriman dua hala (kedua-dua pihak menghantar berbilang mesej secara serentak melalui satu sambungan).
Penstriman Client: Takrif Proto
Add kata kunci stream sebelum jenis permintaan. Client menghantar satu urutan mesej dan, apabila selesai, pelayan 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; }Melaksanakan Penstriman Client pada Pelayan
Gunakan IAsyncStreamReader<T> untuk membaca mesej client apabila mesej itu tiba. Panggil MoveNext() atau lakukan lelaran 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 Penstriman Client daripada Client
Buka panggilan penstriman, tulis mesej dengan RequestStream.WriteAsync(), kemudian isyaratkan penyelesaian dengan CompleteAsync(). Tunggu respons.
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");Penstriman Dua Hala: Takrif Proto
Add stream pada kedua-dua belah untuk komunikasi dupleks penuh. Client dan pelayan boleh menghantar mesej pada bila-bila masa, secara bebas.
service ChatService {
rpc Chat (stream ChatMessage) returns (stream ChatMessage);
}
message ChatMessage {
string user = 1;
string content = 2;
int64 sent_at = 3;
}Melaksanakan Penstriman Dua Hala pada Pelayan
Baca daripada IAsyncStreamReader dan tulis kepada IServerStreamWriter secara serentak. Gunakan Task.WhenAll untuk menjalankan kedua-dua gelung 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);
}Penstriman Dua Hala daripada Client
Hantar dan terima secara serentak dengan melancarkan dua tugas — satu untuk menulis mesej dan satu lagi 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;Kawalan Aliran dan Tekanan Balik
HTTP/2 mempunyai kawalan aliran terbina dalam. Jika penerima perlahan, gRPC menjeda sender secara automatik — sekali gus menghalang limpahan memori. Jangan lakukan penimbalan mesej secara manual; biarkan strim mengendalikannya.
// 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 Strim
Dalam penstriman dua hala, mana-mana pihak boleh menutup bahagian penulisannya sambil terus membaca daripada pihak yang satu lagi. Ini membolehkan client menandakan "selesai menghantar" sambil terus menunggu respons pelayan.
// 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 Penstriman Dua Hala Selamat Utas
Gabungkan System.Threading.Channels dengan penstriman dua hala untuk menghasilkan corak pengeluar-pengguna yang kemas dan mengagihkan mesej kepada banyak pendengar dengan selamat.
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 Sebenar: Saluran Paip Analitik Masa Nyata
Perkhidmatan penyerapan data menerima strim peristiwa telemetri daripada peranti IoT dan menstrim kembali statistik terkumpul dalam masa nyata — kes penggunaan penstriman dua hala 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 });
}
}Semakan Pantas
Dalam penstriman client, bilakah pelayan menghantar respons tunggalnya?
Imbas Kembali: Penstriman Client dan Penstriman Dua Hala
Isi penting:
- Penstriman client: client menghantar banyak mesej, pelayan menghantar satu balasan — sesuai untuk muat naik fail
- Penstriman dua hala: kedua-dua pihak menghantar secara bebas — sesuai untuk Chat dan suapan data langsung
- Gunakan
ReadAllAsync()untuk menggunakan strim denganawait foreach - Panggil
RequestStream.CompleteAsync()untuk menutup separuh bahagian penulisan client - Kawalan aliran HTTP/2 mengendalikan tekanan balik secara automatik — jangan menimbal keseluruhan strim
- System.Threading.Channels sesuai digabungkan dengan penstriman dua hala untuk senario pengagihan mesej
Pelajari C# dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 93
- Pelajaran
- 346
Soalan Lazim
Adakah pelajaran “Penstriman Klien & Dwiarah” percuma?
Ya — teks penuh “Penstriman Klien & Dwiarah” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Akademi C#, tingkat taraf kepada CoddyKit PRO. Kursus Akademi C# merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Penstriman Klien & Dwiarah”?
Bina saluran penstriman klien dan penstriman dwiarah dupleks penuh untuk senario daya pemprosesan tinggi. Anda berlatih Akademi C# menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Akademi C#?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Akademi C# di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.
Berapa lamakah pelajaran “Penstriman Klien & Dwiarah” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Akademi C# ini?
Ya. Setiap pelajaran Akademi C# menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Asas gRPC & Protobuf
- RPC Unary & Penstriman Pelayan
- Penstriman Klien & Dwiarah
- Tarikh Akhir, Pembatalan & Pencegat