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 “
