Akademi C# · Pelajaran

Penstriman Klien & Dwiarah

Bina saluran penstriman klien dan penstriman dwiarah dupleks penuh untuk senario daya pemprosesan tinggi.

Pelajaran 3 daripada 413 langkah

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 uploads

Penutupan 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 dengan await 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
Percuma untuk bermula

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

  1. Asas gRPC & Protobuf
  2. RPC Unary & Penstriman Pelayan
  3. Penstriman Klien & Dwiarah
  4. Tarikh Akhir, Pembatalan & Pencegat
← Kembali ke Akademi C#