Unity’de Ağ Sunucusu Durdurma: OnStopServer() Kullanımı

Unity'de OnStopServer() callback metodunu kullanarak ağ sunucunuzu nasıl güvenli ve verimli bir şekilde durduracağınızı öğrenin. Kaynak yönetimi ve yaygın hatalar.

Unity ile çok oyunculu oyunlar geliştirirken, bir ağ sunucusunun yaşam döngüsünü yönetmek kritik öneme sahiptir. Sunucuyu başlatmak kadar, onu güvenli ve temiz bir şekilde durdurmak da önemlidir. İşte bu noktada OnStopServer() callback metodu devreye girer. Bu makalede, OnStopServer() metodunun ne olduğunu, ne zaman ve neden kullanılması gerektiğini, pratik ipuçlarını, yaygın hataları ve performans etkilerini detaylı bir şekilde inceleyeceğiz.

OnStopServer() Nedir ve Neden Önemlidir?

OnStopServer(), Unity’nin ağ sistemi (özellikle Mirror gibi popüler çözümler) tarafından sağlanan bir callback metodudur. Bu metod, bir Unity ağ sunucusu durdurulduğunda otomatik olarak çağrılır. İster geliştirme ortamında sunucuyu manuel olarak durdurun, ister bir hata nedeniyle çöksün, isterse de planlı bir kapatma işlemi gerçekleştirin, OnStopServer() her zaman devreye girer.

Bu metodun önemi, sunucu kapanmadan önce son temizlik ve veri kaydetme işlemlerini yapabilme yeteneğinden kaynaklanır. Örneğin, sunucuya bağlı tüm istemcilerin bağlantılarının kesilmesi, veritabanı bağlantılarının kapatılması, geçici dosyaların silinmesi veya oyun durumunun kaydedilmesi gibi işlemler burada güvenle gerçekleştirilebilir. Bu sayede hem veri kaybı önlenir hem de sunucu kaynakları düzgün bir şekilde serbest bırakılarak potansiyel bellek sızıntıları veya kilitlenmelerin önüne geçilir.

Temeller: OnStopServer() Ne Zaman Çağrılır?

OnStopServer() metodu, genellikle NetworkManager sınıfından türetilen veya NetworkBehaviour bileşenine sahip bir objede tanımlanır. Bu metodun çağrılma anı, sunucu durdurma işleminin hemen öncesidir. Mirror gibi sistemlerde bu, NetworkServer.Shutdown() çağrıldığında veya NetworkManager.StopHost()/NetworkManager.StopServer() gibi metotlar kullanıldığında gerçekleşir.

Önemli bir ayrım: OnStopServer() ile OnStopClient() veya OnClientDisconnect() metotları karıştırılmamalıdır. OnStopServer() sadece sunucu rolündeki uygulamanın durmasıyla ilgilidir. Bir istemci bağlantısı kesildiğinde OnClientDisconnect() (sunucu tarafında) veya OnStopClient() (istemci tarafında) çağrılırken, OnStopServer() tüm sunucu altyapısının kapanmasıyla ilgilidir.

Basit Bir Kullanım Örneği

Aşağıdaki örnek, NetworkManager sınıfından türetilmiş özel bir yöneticide OnStopServer() metodunun nasıl kullanılabileceğini göstermektedir:

using Mirror;
using UnityEngine;

public class MyNetworkManager : NetworkManager
{
    public override void OnStopServer()
    {
        Debug.Log("Sunucu durduruluyor! Temizlik işlemleri başlatılıyor...");
        // Sunucuya özel temizlik kodları buraya gelir
        // Örneğin, veritabanı bağlantısını kapatma
        // Geçici dosyaları silme
        // Oyun durumunu kaydetme

        base.OnStopServer(); // Temel sınıfın metodunu çağırmayı unutmayın
        Debug.Log("Sunucu temizliği tamamlandı.");
    }

    public override void OnStartServer()
    {
        base.OnStartServer();
        Debug.Log("Sunucu başlatıldı.");
    }
}

NetworkBehaviour sınıfını kullanan bir obje için de benzer bir yapı mevcuttur. Ancak, NetworkBehaviour üzerindeki OnStopServer() genellikle o objeye özel kaynakların temizliği için kullanılırken, genel Unity ağ sunucusu yönetimi NetworkManager üzerinde yapılır.

Pratik İpuçları

OnStopServer() metodunu kullanırken verimliliği ve güvenilirliği artırmak için bazı ipuçları:

1. Kaynak Temizliği ve Bellek Yönetimi

Sunucunuzun uzun süreler boyunca çalışması veya sıkça yeniden başlatılması durumunda, kaynak sızıntılarını önlemek kritiktir. OnStopServer(), bu tür sorunları çözmek için ideal bir yerdir. Özellikle olay aboneliklerini (event subscriptions) kaldırmak, ağ bağlantılarını kapatmak (örneğin, harici veritabanı bağlantıları), açık dosya tanıtıcılarını serbest bırakmak ve oluşturulan geçici objeleri yok etmek burada yapılmalıdır.

public override void OnStopServer()
{
    Debug.Log("Sunucu durduruldu. Kaynaklar temizleniyor...");
    // Örnek: Bir olaya abone olduysanız aboneliği kaldırın
    // MyGameEvents.OnGameOver -= HandleGameOver;

    // Örnek: Veritabanı bağlantısını kapatma
    // if (databaseConnection != null) databaseConnection.Close();

    base.OnStopServer();
}

2. Oyun Durumunu Güvenle Kaydetme

Çok oyunculu oyunlarda, sunucu beklenmedik bir şekilde kapandığında oyuncu ilerlemelerinin veya oyun dünyası durumunun kaybolması büyük bir sorun olabilir. OnStopServer(), sunucu durmadan önce kritik oyun verilerini (oyuncu envanterleri, dünya değişiklikleri, skorlar vb.) veritabanına veya kalıcı depolama birimine kaydetmek için son bir fırsat sunar. Bu, özellikle aniden kapanma durumlarında veri kaybını minimize etmeye yardımcı olur.

3. Harici Servislere Bildirim

Eğer Unity ağ sunucusu, bir ana sunucuya (master server) veya diğer harici servislere kayıtlıysa, sunucu kapanmadan önce bu servislere kendisinin artık aktif olmadığını bildirmek iyi bir uygulamadır. Bu sayede, istemciler veya diğer servisler kapalı bir sunucuya bağlanmaya çalışmaz. Örneğin, bir oyun sunucusu listesinden kendisini kaldırabilir.

Yaygın Hatalar ve Çözümleri

1. Kaynakları Temizlemeyi Unutmak

Hata: Geliştiricilerin en sık yaptığı hatalardan biri, sunucu başlatıldığında edinilen kaynakları (bellek, dosya, ağ bağlantısı) OnStopServer() içinde serbest bırakmayı unutmaktır. Bu durum, zamanla bellek sızıntılarına ve sunucunun kararsız çalışmasına yol açabilir.

Çözüm: Sunucu başlatıldığında (OnStartServer() veya Awake()/Start() içinde) edindiğiniz her kaynağın, OnStopServer() içinde uygun şekilde serbest bırakıldığından emin olun. Özellikle olay abonelikleri ve açık dosya/ağ bağlantıları için dikkatli olun.

2. Uzun Süren veya Blocking İşlemler

Hata: OnStopServer() içinde çok uzun süren veya ana iş parçacığını (main thread) bloke eden işlemler yapmak, sunucunun kapanış sürecini gereksiz yere uzatabilir veya hatta kilitlenmesine neden olabilir. Özellikle büyük veri kaydetme işlemleri veya yavaş ağ istekleri bu kategoriye girer.

Çözüm: Kritik olmayan veya uzun süren işlemleri mümkünse asenkron (async) metotlarla yönetin veya bu işlemleri sunucunun yaşam döngüsünün başka bir aşamasına taşıyın. OnStopServer() içindeki işlemler hızlı ve verimli olmalıdır. Eğer veri kaydetme gibi işlemler kaçınılmazsa, bunu mümkün olan en optimize şekilde yapın.

3. İstemci Tarafı Mantığı Uygulamak

Hata: OnStopServer(), adından da anlaşılacağı gibi sunucu tarafı bir callback’tir. Ancak bazen geliştiriciler, burada istemci tarafı objeleri veya mantığı işlemeye çalışabilir.

Çözüm: OnStopServer() içinde sadece sunucuya özgü mantık ve kaynak yönetimi olduğundan emin olun. İstemci tarafı objeleri veya UI elementleri ile ilgili işlemler burada yapılmamalıdır.

Performans ve Optimizasyon Notları

OnStopServer() metodu, genellikle performans açısından kritik bir alan değildir, çünkü sunucu zaten kapanma sürecindedir. Bu noktada öncelik, sunucuyu güvenli ve temiz bir şekilde kapatmaktır. Ancak, yine de bazı noktalara dikkat etmek faydalıdır:

  • Hız: OnStopServer() içindeki işlemlerin mümkün olduğunca hızlı tamamlandığından emin olun. Uzun süren işlemler, kullanıcı deneyimini kötü etkilemese de (sunucu zaten kapanıyor), sunucunun kapalı olarak işaretlenmesi veya kaynakların serbest bırakılması gecikebilir.
  • Verimlilik: Gereksiz hesaplamalardan veya kaynak tüketiminden kaçının. Sadece gerçekten gerekli olan temizlik ve kaydetme işlemlerini yapın.
  • Hata Yönetimi: Temizlik işlemleri sırasında oluşabilecek hataları (örneğin, veritabanı bağlantısı kesintisi) uygun try-catch bloklarıyla yönetin. Bir hata, sunucunun tamamen kapanmasını engellememeli veya daha fazla soruna yol açmamalıdır.

Sonuç olarak, OnStopServer() metodu, Unity ağ sunucusu geliştiricileri için vazgeçilmez bir araçtır. Bu metodu doğru ve bilinçli kullanmak, hem daha stabil ve güvenilir sunucular oluşturmanıza yardımcı olur hem de oyun verilerinin bütünlüğünü korur. Unutmayın, iyi bir başlangıç kadar, iyi bir kapanış da önemlidir!

Leave a Reply

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir