← Tüm yazılar

SignalR ile oda, hazır durumu ve maç başlangıcı

Gerçek zamanlı bir lobide bağlantıyı gruba almak ile oyuncunun maça hazır olduğunu kabul etmek farklı adımlardır. Oda üyeliğini kurmadan hazır mesajını işlemiyorum.

t.Turgay
SignalR ile oda, hazır durumu ve maç başlangıcı

Bir oyuncunun “hazırım” demesiyle maçın başlatılabilir olması farklı kararlar. Gerçek zamanlı iletişim, bu kararı bütün istemcilere hızlıca duyurur; kararın sahibini istemciye bırakmaz. Arşivimdeki oyun sunucusu akışlarını, SignalR oda üyeliği ve sunucu durumunun sınırları üzerinden açıklıyorum.

Bağlantıyı gruba sunucu ekler

Bu bağımsız ASP.NET Core parçasında yalnız demo adlı oda kabul ediliyor. Önce JoinLobby("demo"), sonra Ready(true) çağrılır. Hub sınıfı tek başına çalışan uygulama değildir; AddSignalR, MapHub, kimlik doğrulama yapılandırması ve istemci bağlantısı ayrıca gerekir.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
[Authorize]
public sealed class DemoHub:Hub
{
    public async Task JoinLobby(string room)
    {
        if(room!="demo")throw new HubException("Unknown room");
        Context.Items["room"]=room;
        await Groups.AddToGroupAsync(Context.ConnectionId,room);
    }
    public async Task Ready(bool ready)
    {
        if(!Context.Items.TryGetValue("room",out var room))throw new HubException("Join first");
        await Clients.Group((string)room!).SendAsync("PlayerReady",Context.ConnectionId,ready);
    }
}

Authorize, hub erişiminin kimlik gerektirdiğini belirtir. Context.Items o bağlantının oda bilgisini taşır; Groups.AddToGroupAsync bağlantıyı bildirim grubuna ekler. Ready çağrısı odaya PlayerReady olayını yollar. Odaya katılmadan çağrı yapılırsa Join first hatası üretilir. Örneğin yaptığı bu; kalıcı oda deposu veya maç başlatma kuralı içermez.

SignalR grubu bir oyuncu listesi değildir

Grup, mesaj yönlendirme mekanizmasıdır. Üye sayımı, hazır oyuncuların kalıcı kaydı veya oyunun tek doğru durumu gibi kullanılmamalı. Bağlantı kimliği de oyuncunun kalıcı kimliği değildir; kopma/yeniden bağlanmada değişebilir. Aynı oyuncunun birden fazla sekmesini ve bağlantısını düşünmek gerekir.

Sunucu, oturumdan kullanıcı kimliğini çıkarıp oyun oyuncusuyla eşler. İstemcinin gönderdiği userId ile başka oyuncunun hazır durumunu değiştirmesine izin verilmez. Odaya katılma sırasında oda varlığı yanında davet, kapasite veya maçın başlamış olması gibi kurallar da gerçek durum deposunda denetlenebilir.

Maçı başlatmak bir durum geçişidir

İki oyuncu aynı anda Ready(true) gönderirse “herkes hazır mı?” sorusunun iki kez evet dönmesi mümkündür. Her kontrolün ardından ayrı ayrı maç üretirsem iki maç açılabilir. Bekleme → başlatılıyor → başladı geçişini sunucuda atomik korumak gerekir; yalnız gruba MatchStarted mesajı göndermek bunu sağlamaz.

İşlem kimliği veya sürüm numarası taşıyan oda snapshot'ı bu akışı açıklaştırabilir. Olay mesajı “ne değişti?” bilgisidir; yeniden bağlanan istemci “şu an ne var?” sorusuna güvenilir bir snapshot ile cevap almalı. Kaçırılmış birkaç olayın toplamından doğru durumu tahmin etmek zorunda kalmamalı.

Kopma ve yeniden bağlanma

Bir bağlantının grupta olması kalıcı oyuncu üyeliği yerine geçmez. Yeniden bağlanmada grup ve oyun üyeliği uygulama tarafından tekrar doğrulanmalı; istemci reconnect oldu diye önceki bütün yetkilerin ve durumun kendiliğinden kurulduğunu varsaymam. Bir oyuncu ayrılırken hazır bilgisinin nasıl temizleneceği veya korunacağı da oyun kuralıdır.

Çok sunuculu ortamda bir hub örneğinin belleğindeki liste bütün odaların ortak durumu değildir. Paylaşılan oda deposu ve SignalR ölçekleme çözümü farklı görevler taşır. Küçük tek süreçli denemede çalışması, dağıtık koordinasyonun tamamlandığını göstermez.

Güven sınırı mesajda da sürer

Yöntem argümanları doğrulanmalı, aşırı mesaj üretimi sınırlandırılmalı ve istemciye gereksiz özel bilgi gönderilmemeli. Hub metotlarında güvenli kullanıcı hatası için HubException kullanılabilir; iç SQL veya stack ayrıntısını mesaj olarak taşımam. İstemci bildirimi alınca sunucu kararını gösterir; kendi belleğinde herkesi hazır yapıp maçı yetkili saymaz.

Testte odaya girmeden Ready, bilinmeyen oda, iki eşzamanlı hazır isteği, kopma ve yeniden katılma bulunmalı. İlk örnek PlayerReady olayını gösterir; tam maç başlatma akışı için yukarıdaki durum ve tekilleştirme sözleşmeleri ayrıca uygulanır.

SignalR hub modeli; Grup üyeliği ve sınırları.

✳ Bu yörüngenin sonuna geldin.
Diğer yazıları keşfet →
turgay.Biraz kod, biraz piksel, bolca merak.© 2026 · Dünya’dan sevgilerle ✳