Makale 5: Sunucu Uygulamalarının Konfigürasyon Dosyası İle Yapılandırılması

Remoting uygulamaları programatik olarak configure edilebileceği gibi, gerekli configuration dosyalarını okumaları sağlanarak da configure edilebilirler (ör: machine.config).

Bir önceki makalemizde (Makale 4: Sunucu Uygulamalarının Çalışma Zamanında Yapılandırılması) gördüğümüz üzere Remoting server’larının channel ismi, port, priority gibi özellikleri bulunmakta. Şimdi uygun bir configuration dosyası hazırlayarak uygulamamızı daha az kod yazarak nasıl configure edebileceğimizi görelim.

İPUCU

Remoting uygulamalarının configuration dosyaları kullanılarak configure edilmesi configuration’larda değişiklik yapılması durumunda uygulamanın yeniden derlenmesine olan ihtiyacı ortadan kaldıracağı için daha avantajlıdır.

Yeni bir Visual Studio projesi oluşturup, proje tipi olarak “Console Application” seçeneğini seçelim ve proje ismini de “ConfigSerAppConfigFile” olarak verelim. Solution içerisine “Class Library” tipinde yeni bir proje daha ekleyelim. Bu class library projesinin ismini “ConfigSerAppCFile.RemObjects” olarak verelim. Oluşturduğumuz class library projesine “Configure a server application programmatically” başlığı altında yaptığımız örnekte kullandığımız “MyRemotableObject” class’ını birebir olarak ekleyelim.

“ConfigSerAppCFile.RemObjects” projesini “ConfigSerAppConfigFile” projesine referans olarak ekledikten sonra console application projemize yeni bir configuration dosyası ekleyerek ismini “ConfigSerAppConfigFile.exe.config” olarak değiştirelim. Bu dosya içeriğini de aşağıdaki şekilde değiştirelim.

ConfigSerAppConfigFile.exe.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.runtime.remoting>
        <application>
            <channels>
                <channel ref="tcp" port="1234">
                    <serverProviders>
                        <formatter ref="soap"/>
                    </serverProviders>
                </channel>
            </channels>
            <service>
                <wellknown
                    mode="Singleton"
                    type="ConfigSerAppCFile.RemObjects.MyRemotableObject, ConfigSerAppCFile.RemObjects"
                    objectUri="MyRemotableType.rem"
                />
            </service>
        </application>
    </system.runtime.remoting>
</configuration>

Yukarıdaki kodlarda görmüş olduğunuz gibi channel bilgileri, remotable type bilgileri ve formatter bilgileri configuration dosyaları içerisinde tanımlanabilmektedir.

Bu kodumuzdaki en önemli nokta channel ve formatter tag’ları içerisinde bulunan ref attribute’üdür. Bu attribute machine.config dosyasında tanımlanmış olan bilgilere referans vermek için kullanılır. ref attribute’ünün yerine type attribute’ünün kullanılması durumunda ise ref attribute’ünün kullanılmasına gerek bulunmamaktadır. Örneğin MyCustomChannel isminde bir class oluşturduğunumuzu, bu class’ı daha önce bahsettiğimiz IChannelReceiver interface’inden implement ettiğimizi ve class’ın içerisinde bulunduğu assembly’nin isminin de CustomChannelAssembly olduğunu düşünürseniz, type attribute’ü şu şekilde tanımlanmalıdır:

“type” attribute’ü kullanımı

<channel type="MyCustomChannel,MyCustomChannelAssembly" port="1234">
    <serverProviders>
        <formatter ref="soap"/>
    </serverProviders>
</channel>

Buradaki type attribute’ü kullanımı birebir olarak uygun şekilde geliştirilen formatter’lar için de geçerlidir.

Son olarak da uygulamamızı tanımlamış olduğumuz configuration dosyasını okuyacak ve Remoting configuration’ını kendi kendine yapacak şekile getirelim.

RemotingServer.cs

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace ConfigSerAppConfigFile
{
    public class RemotingServer
    {
        static void Main(string[] args)
        {
            RemotingConfiguration.Configure("../../ConfigSerAppConfigFile.exe.config", false);
            TcpChannel tcpChannel = ChannelServices.RegisteredChannels[0] as TcpChannel;

            if (tcpChannel == null)
            {
                Console.WriteLine("Invalid configuration file...");
                Console.WriteLine("Press Enter to exit.");
                Console.ReadLine();
            }

            WellKnownServiceTypeEntry[] registeredWellKnownServiceTypes = RemotingConfiguration.GetRegisteredWellKnownServiceTypes();

            foreach (WellKnownServiceTypeEntry type in registeredWellKnownServiceTypes)
            {
                Console.WriteLine("{0} is registered.", type.TypeName);
            }

            string[] urls = tcpChannel.GetUrlsForUri("MyRemoteObject.rem");
            string objectUrl = urls[0];
            string objectUri = null;
            string channelUri = tcpChannel.Parse(objectUrl, out objectUri);

            Console.WriteLine("The URL for the object is {0}.", objectUrl);
            Console.WriteLine("The URI for the object is {0}.", objectUri);
            Console.WriteLine("The URI for the channel is {0}.", channelUri);
            Console.WriteLine("Remoting server is now listening...");
            Console.WriteLine("Press Enter to exit.");
            Console.ReadLine();
        }
    }
}

Yazmış olduğumuz kodları sırasıyla şu şekilde açıklayalım.

  • RemotingConfiguration class’ının sahip olduğu static olarak işaretlenmiş Configure method’unu kullanarak configuration bilgilerimizi barındıran configuration dosyasını okumasını ve Remoting configuration’ını bu dosyadaki bilgiler doğrultusunda yapmasını sağladık.
  • Remoting configuration’ı içerisinde “WellKnownService” olarak register edilmiş olan remotable type’ları registeredWellKnownServiceTypes değişkenine atadık.
  • registeredWellKnownServiceTypes değişkenini foreach döngüsü içerisine alarak register edilmiş object’lerin TypeName bilgilerini ekrana, sadece bilgi amaçlı olarak, yazdırdık..
  • Servisimiz ile ilgili URL ve URI bilgilerini sadece bilgi edinmek amacıyla ekrana yazdırdık.

Visual Studio üzerinde uygulamayı çalıştırdığımızda karşımıza aşağıdaki ekran gelir:

UYARI

Ekran görüntüsü içerisinde görünen IP adresi bilgisayarınızın network konfigürasyonuna göre farklılık gösterebilir.

RemotingServer class’ı içerisinde kullandığımız bazı method’lar ve görevleri aşağıdaki gibidir.

Method


Görev
RemotingConfiguration.Configure Configuration dosyasının Remoting uygulamasının configuration’ı için yüklenmesini sağlar. Örnek uygulamada verilen path’in başında herhangi bir bilgi olmadığında uygulama configuration dosyasını kendi bulunduğu path içerisinde arayacaktır. Dosyanın bulunamaması durumunda System.IO.FileNotFoundException throw edilir. Yazmış olduğumuz örnekte configuration dosyasının iki üst klasörde olmasından dolayı bu path’in başına “../../” (2 defa nokta, nokta, slash) ekleyerek dosyanın iki üst klasörde aranmasını sağladık.
RemotingConfiguration.GetRegisteredWellKnownServiceTypes Configuration dosyasında bulunan <service> nodu’u içerisinde register edilen remotable type’ların listesinin alınabileceği method’dur.

UYARI

Remoting uygulamanızın üzerinde çalışacağı port bilgisini yazarken ilgili port’un başka bir uygulama tarafından kullanılmadığından emin olunuz. Örneğin IIS’in 80. port üzerinde çalıştığını düşünürseniz ve siz de uygulamanızı 80. port üzerinden çalışacak şekilde ayarlarsanız aşağıdaki hata ile karşılaşırsınız:

System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *