0Pricing
C# Academy · Ders

İstemci ve Çift Yönlü Akış

Yüksek aktarım hızı gerektiren senaryolar için istemci akışı ve tam çift yönlü akış kanalları oluşturun.

İstemci ve Çift Yönlü Akış, CoddyKit'te ücretsiz bir C# Academy dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C# Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C# Academy kursu toplamda 4 dersten oluşur.

İstemci Akışı ve Çift Yönlü Akış

gRPC, tekli ve sunucu akışının yanı sıra istemci akışını (istemci birçok ileti gönderir, sunucu bir kez yanıt verir) ve çift yönlü akışı (her iki taraf da tek bir bağlantı üzerinden aynı anda birden çok ileti gönderir) destekler.

İstemci Akışı: Protokol Tanımı

İstek türünün önüne stream anahtar sözcüğünü ekleyin. İstemci bir ileti dizisi gönderir ve işlem tamamlandığında sunucu tek bir yanıt döndürür.

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; }

Sunucuda İstemci Akışını Uygulama

İstemci iletilerini geldikleri anda okumak için IAsyncStreamReader<T> kullanın. MoveNext() çağrısı yapın veya ReadAllAsync() ile yineleyin.

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 };
}

İstemciden İstemci Akışı Çağrısı

Akış çağrısını açın, iletileri RequestStream.WriteAsync() ile yazın, ardından CompleteAsync() ile tamamlandığını bildirin. Yanıtı bekleyin.

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");

Çift Yönlü Akış: Protokol Tanımı

Tam çift yönlü iletişim için her iki tarafa da stream ekleyin. İstemci ve sunucu, birbirlerinden bağımsız olarak istedikleri zaman ileti gönderebilir.

service ChatService {
  rpc Chat (stream ChatMessage) returns (stream ChatMessage);
}

message ChatMessage {
  string user    = 1;
  string content = 2;
  int64  sent_at = 3;
}

Sunucuda Çift Yönlü Akışı Uygulama

IAsyncStreamReader üzerinden eşzamanlı olarak okuyun ve IServerStreamWriter öğesine yazın. Her iki döngüyü aynı anda çalıştırmak için Task.WhenAll kullanın.

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);
}

İstemciden Çift Yönlü Akış

İki Task başlatarak eşzamanlı biçimde gönderip alın — biri ileti yazmak, diğeri yanıtları okumak için.

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;

Akış Denetimi ve Geri Basınç

HTTP/2, yerleşik akış denetimine sahiptir. Tüketici yavaşsa gRPC, bellek taşmasını önlemek için göndericiyi otomatik olarak duraklatır. İletileri el ile arabelleğe almayın; akışın bunu yönetmesine izin verin.

// 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

Yarı Kapatma ve Akışın Tamamlanması

Çift yönlü akışta taraflardan biri, diğer taraftan okumayı sürdürürken yazma yönünü kapatabilir. Bu sayede istemci, sunucu yanıtlarını beklemeyi sürdürürken "gönderme tamamlandı" sinyali verebilir.

// 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);
}

İş Parçacığı Güvenli Çift Yönlü Akış için Kanalları Kullanma

System.Threading.Channels ile çift yönlü akışı birleştirerek iletileri çok sayıda dinleyiciye güvenli biçimde dağıtan temiz bir üretici-tüketici örüntüsü oluşturun.

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);
}

Gerçek Dünya: Gerçek Zamanlı Analiz Veri İşleme Hattı

Bir veri alma hizmeti, IoT cihazlarından gelen telemetri olayları akışını kabul eder ve toplu istatistikleri gerçek zamanlı olarak geri aktarır — çift yönlü akış için mükemmel bir kullanım örneği.

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 });
    }
}

Hızlı Kontrol

İstemci akışında sunucu tek yanıtını ne zaman gönderir?

Özet: İstemci ve Çift Yönlü Akış

Temel çıkarımlar:

  • İstemci akışı: istemci birçok ileti gönderir, sunucu bir yanıt gönderir — dosya yükleme için idealdir
  • Çift yönlü akış: her iki taraf bağımsız olarak gönderir — sohbet ve canlı veri akışları için idealdir
  • Akışları await foreach ile tüketmek için ReadAllAsync() kullanın
  • İstemcinin yazma tarafını yarı kapatmak için RequestStream.CompleteAsync() çağrısını yapın
  • HTTP/2 akış denetimi geri basıncı otomatik olarak yönetir — akışların tamamını arabelleğe almayın
  • System.Threading.Channels, dağıtım senaryolarında çift yönlü akışla iyi çalışır

Sıkça Sorulan Sorular

“İstemci ve Çift Yönlü Akış” dersi ücretsiz mi?

Evet — “İstemci ve Çift Yönlü Akış” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C# Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C# Academy kursu toplamda 4 dersten oluşur.

“İstemci ve Çift Yönlü Akış” dersinde ne öğreneceğim?

Yüksek aktarım hızı gerektiren senaryolar için istemci akışı ve tam çift yönlü akış kanalları oluşturun. C# Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

C# Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te C# Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.

“İstemci ve Çift Yönlü Akış” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu C# Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her C# Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. gRPC ve Protobuf Temelleri
  2. Tekli ve Sunucu Akışlı RPC'ler
  3. İstemci ve Çift Yönlü Akış
  4. Son Tarihler, İptal ve Araya Giriciler
← C# Academy Sayfasına Dön