Silverlight 3.0 uygulamalarını birbiri ile konuşturun

0 dakikada yazıldı

5918 defa okundu

Düzenle

Bir web sitesi içerisinde birden çok Silverlight uygulamasını beraber
kullanıyor olabilirsiniz veya belki de aynı web sitesinde sizin
hazırladığınız bir Silverlight uygulamasının yanı sıra bir de başka bir
yazılımcının/tasarımcının hazırladığı Silverlight uygulaması
bulunuyordur. Peki hiç bu iki uygulamanın birbirinden haberdar
olabileceğini ve karşılıklı haberleşebileceklerini düşündünüz mü?

Eminim ki hemen aklınıza gelecek çözüm sunucu tarafından uygulamaları
birbiri ile konuşturmak olacaktır oysa artık Silverlight 3.0 ile beraber
LocalMessaging denilen ve Named Pipes mantığına çok benzeyen bir
sistem ile uygulamaları birbirleri ile haberleşebiliyorlar. Birden çok
Silverlight uygulaması ister aynı sayfada, ister tarayıcınızın ayrı
tablarında ister farklı tarayıcılarda olsun aynı makinede çalıştıkları
sürece birbirleri ile sunucudan bağımsız olarak tamamen istemci
tarafında konuşabiliyorlar.

Neler yapılabilir?

Aslında bu yapı ile bir çok farklı senaryo düşünülebilir. Her iki veya
üç Silverlight uygulamasını da sizin hazırladığınızı düşünürsek belki de
uygulamalar arasına interaksyon sağlayabilirsiniz. Kullanıcının bir
uygulamada yaptığı değişiklik bir diğerinde de bazı farklı mekanizmaları
tetikleyebilir.

Bir diğer senaryoda ise belki de hiç kodlarına sahip olmadığınız bir
Silverlight uygulaması ile sizin uygulamanızın birbiri ile istemci
tarafında konuşması gerektiğinde ortak belirlenen bir kanal üzerinden
uygulamaların haberleşmesini sağlayarak entegrasyon sağlayabilirsiniz.
Daha belki de benim aklıma gelmeyen birçok farklı mekanizma mümkün
olabilir.

Mutfağa geçelim....

Teorik kısmı atlattıktan sonra gelin biraz da LocalMessaging sistemini
nasıl kullanabileceğimize göz atalım. Özünde LocalMessaging yapısı
Named Pipes mantığı ile işliyor. Yani iki tarafın bir biri ile
haberleşmesi için bir kanala ihtiyacınız var. Kanallar String tipinde
isimler ile birbirinden ayırt ediliyor. Kanal ismine göre dinleyici
uygulama söz konusu kanalı dinlerken veri gönderecek uygulama da yine
aynı kanal ismini kullanarak veri gönderme işlemini yapabiliyor.

Yapacağımız örnekte uygulamalarımızdan birinde yer alan düğmeye
bastığımızda diğerinde bir animasyon çalıştıracağız. Bu sistemin
gerçekleşebilmesi için iki numaralı uygulama "MesajKanali" adındaki
bir kanalı dinlemeye başlarken aynı kanala bir numaralı uygulama ise iki
numaralı uygulamanın anlayabileceği bir mesaj gönderecek. Gelin ilk
olarak mesajı gönderecek olan uygulama ile işimize başlayalım.

[XAML]

<UserControl
x
:Class="SilverlightApplication6.MainPage"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   Width="400"
Height
="300">

    <Grid
x
:Name="LayoutRoot"
Background
="White">

        <Button
Content
="Mesaj Gönder" x:Name="btnGonder"
Click
="btnGonder_Click"/>

    </Grid>

</UserControl>

Uygulamamızın ekranında basit bir düğme bulunuyor. Söz konusu düğmeye
basıldığında mesaj gönderme işlemini başlatacağız.

[VB]

    Private Sub btnGonder_Click(ByVal sender As System.Object, ByVal e As
System.Windows.RoutedEventArgs)

        Dim MesajGonderici As New
Messaging.LocalMessageSender("MesajKanali", "localhost")

        MesajGonderici.SendAsync("BASLA")

    End Sub

[C#]

        private void btnGonder_Click(object sender, RoutedEventArgs e)

        {

            System.Windows.Messaging.LocalMessageSender MesajGonderici =

                new
System.Windows.Messaging.LocalMessageSender("MesajKanali", "localhost");

            MesajGonderici.SendAsync("BASLA");

        }

Yukarıda gördüğünüz kod içerisindeki ilk satırda mesaj gönderebilmek
için bir LocalMessageSender yaratıyoruz. Söz konusu sınıfın
constructor'ı bizden kanal ismini ve mesajın gönderileceği domainin
adını istiyor. Bizim kullanacağımız kanalı ismi şimdilik
"MesajKanali" olacak. Kanalimizi ve mesaj göndericimizi
yarattığımıza göre artık söz konusu mesaj göndericinin SendAsync
metodu ile mesajımızı bu kanalı dinleyen herkese gönderebiliriz.
SendAsync metodunun sonundaki Async uzantısından da anlayabileceğiniz
üzere işlem asenkron olarak yapılacak. Yani mesaj gönderdildikten sonra
durumdan haberdar olmak istiyorsanız LocalMessageSender'ın
SendCompleted event'ını yakalamanız gerekiyor.

Eğer gönderdiğiniz mesaj herhangi bir hedef domain'e bakılmaksızın söz
konusu kanalı dinleyen herkese gönderilsin istiyorsanız aşağıdaki
şekilde ikinci parametre olarak Global değerini de verebilirsiniz.

[VB]

        Dim MesajGonderici As New
Messaging.LocalMessageSender("MesajKanali",
System.Windows.Messaging.LocalMessageSender.Global)

Gördüğünüz gibi mesaj gönderme işlemi epey basit. Maalesef ki mesajlar
sadece String tipinde olabiliyor. Eğer .NET objeleri göndermek
isterseniz uygun XML Serializer'ları kullanabilirsiniz. Örneğimizde biz
"BASLA" mesajını gönderiyoruz. Tabi bu mesajın alıcı tarafında da
alındıktan sonra bir anlam ifade etmesi gerekecek. Onun için de
dinleyici tarafında uygun kodu birazdan yazacağız.

Dinleyici nerede?

Sıra geldi dinleyici uygulamayı hazırlamaya. Dinleyici uygulamamızda
basit bir animasyon olacak ve kendisine diğer uygulamadan uygun mesaj
gönderildiği anda bu animasyon başlatılacak. Siz örneklerinizde farklı
senaryolar uygulayabilirsiniz.

[XAML]

<UserControl
x
:Class="SilverlightApplication7.MainPage"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   Width="400"
Height
="300">

    <UserControl.Resources>

        <Storyboard
x
:Name="Animasyon">

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"

                                         
Storyboard.TargetName
="rectangle"

                                         
Storyboard.TargetProperty
="(UIElement.Opacity)">

                <SplineDoubleKeyFrame KeyTime="00:00:00"
Value
="0"/>

                <SplineDoubleKeyFrame KeyTime="00:00:01"
Value
="1" KeySpline="1,0,1,1"/>

                <SplineDoubleKeyFrame KeyTime="00:00:02"
Value
="0" KeySpline="0,1,1,1"/>

            </DoubleAnimationUsingKeyFrames>

        </Storyboard>

    </UserControl.Resources>

    <Grid
x
:Name="LayoutRoot"
Background
="White">

        <Rectangle
Height
="100" Width="100"
Fill
="Red" Opacity="0" x:Name="rectangle"/>

    </Grid>

</UserControl>

Yukarıda XAML'ını gördüğünüz uygulama Dinleyici uygulamamız. İçerisinde
bir Rectangle ve basit bir de animasyon bulunuyor. Artık Dinleyici
uygulamamız içerisinde de bir dinlayici nesnesi tanımlayıp mesajın
gönderileceği kanalı dinlemeye başlamanın zamanı geldi.

[VB]

    Private Sub MainPage_Loaded(ByVal sender As Object,
ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

        Dim Gonderebilenler As New
List(Of String)

        Gonderebilenler.Add("localhost")

        Dim MesajDinleyici As New
Messaging.LocalMessageReceiver("MesajKanali",
Messaging.ReceiverNameScope.Domain, Gonderebilenler)

        AddHandler
MesajDinleyici.MessageReceived, AddressOf MesajDinleyici_MessageReceived

        MesajDinleyici.Listen()

    End Sub

[C#]

        public MainPage()

        {

            InitializeComponent();

            this.Loaded += new RoutedEventHandler(MainPage_Loaded);

        }

 

        void MainPage_Loaded(object sender, RoutedEventArgs e)

        {

            List<String> Gonderebilenler = new List<string>();

            Gonderebilenler.Add("localhost");

            System.Windows.Messaging.LocalMessageReceiver MesajDinleyici =

                new
System.Windows.Messaging.LocalMessageReceiver("MesajKanali",

                    System.Windows.Messaging.ReceiverNameScope.Domain,
Gonderebilenler);

            MesajDinleyici.MessageReceived += new EventHandler<System.Windows.Messaging.MessageReceivedEventArgs>(MesajDinleyici_MessageReceived);

            MesajDinleyici.Listen();

        }

Uygulamamız açıldığı gibi hemen işlemlere başlıyoruz. İlk olarak
dinlemek istediğimiz kanalların bulunduğu domain'lerin bir listesini
yaratmamız gerek. Bunun için bir String listesi yeterli olacaktır. Bu
liste içerisinde dinleyeceğiniz kanalın hangi domain'den geleceğini
belirlemiş oluyorsunuz. Aksi halde herhangi bir domain'den yola çıkan ve
aynı kanal ismini kullanan uygulamalar ile çakışmanız olası.

Elimizde dinlenecek domain listedi Gonderebilenler değişkeninde
bulunduktan sonra MesajDinleyici'mizi yaratabiliriz.
LocalMessageReceiver sınıfından aldığımız değişkenimizi yaratırken
toplam üç parametre vermemiz gerek. Bunlardan ilki dinleyeceğimiz kanalı
String adı, ikincisi ise dinleme işlemini hangi çapta yapmak
istediğimiz. Global anlamda dinleyerek Gonderebilenler
listemizdeki tüm alan adlarını dinleyebileceğimiz gibi Domain
çapından ilerleyerek sadece bulunduğumuz alan adını dinleyebiliriz. Eğer
sadece bulunduğunuz alan adını dinleyecekseniz aslında
Gonderebilenler listesine gerek yok ama yine de örneğimizde eksik
olmasın diye bir parametremiz Nothing/Null şeklinde geçmeyelim
istedim.

Bir sonraki adımda MesajDinleyici nesnemizim MessageReceived
event'ını da ayrı bir event-listener'a bağlamamız gerekiyor ki mesaj
geldiğinde durumdan haberdar olabilelim. Tabi son olarak
LocalMessageReceiver'ın Listen metodunu da çağırıyor ve dinleme
işlemini başlatıyoruz.

[VB]

    Private Sub MesajDinleyici_MessageReceived(ByVal sender As Object,
ByVal e As
System.Windows.Messaging.MessageReceivedEventArgs)

        If e.Message = "BASLA" Then Animasyon.Begin()

    End Sub

[C#]

        void
MesajDinleyici_MessageReceived(object
sender, System.Windows.Messaging.MessageReceivedEventArgs e)

        {

            if (e.Message == "BASLA") Animasyon.Begin();

        }

Dinleme işlemine bağladığımız event-listener içerisinden yer alan
MessageReceivedEventArgs üzerinden Message Property'si ile gelen mesajı
alabilirsiniz. Bu mesajı farklı şekilerde Parse ederek anlam
kazandırabileceğiniz gibi basit bir şekilde komut anlamında String
karşılaştırma yaparak da yapacağınız işlemleri belirleyebilirsiniz. Biz
örneğimizde BASLA mesajı geldiğinde elimizdeki animasyonu
çalıştırıyoruz.

Bu noktadan sonra eğer Dinleyici uygulama hemen, anında mesajı gönderen
kişiye bir cevap vermek isterse MessageReceivedEventArgs ile beraber
gelen Response özelliğini kullanabilir. Böylece belki gelen komut için
bir cevap belki de başka bir bilgi gönderilebilir.

[VB]

    Private Sub
MesajDinleyici_MessageReceived(
ByVal sender
As Object,
ByVal e
As
System.Windows.Messaging.MessageReceivedEventArgs)

        If e.Message =
"BASLA" Then
Animasyon.Begin()

        e.Response = "OLDU"

    End Sub

[C#]

        void
MesajDinleyici_MessageReceived(
object sender,
System.Windows.Messaging.
MessageReceivedEventArgs e)

        {

            if (e.Message ==
"BASLA") Animasyon.Begin();

            e.Response="OLDU";

        }

Burada tanımlanan Response değişkeni içerisinde bilgi otomatik olarak
mesajı gönderen uygulamayı geri gidecektir. Geri giden bu veriyi mesajı
gönderen uygulamanın yakalayabilmesi için kesinlikle kendi içerisinde
LocalMessageSender'ın SendCompleted event'ını dinlemesi gerekir.
Söz konusu event'ın SendCompletedEventArgs parametresinin
Response Property'si dinleyiciden gönderilen mesajı içerecektir.
Mesajın göndericisine ait örnek kodu aşağıda inceleyebilirsiniz.

[VB]

    Private Sub btnGonder_Click(ByVal sender As System.Object, ByVal e As
System.Windows.RoutedEventArgs)

        Dim MesajGonderici As New
Messaging.LocalMessageSender("MesajKanali", "localhost")

        AddHandler
MesajGonderici.SendCompleted, AddressOf x_SendCompleted

        MesajGonderici.SendAsync("BASLA")

    End Sub

 

    Private Sub x_SendCompleted(ByVal sender As Object,
ByVal e As
System.Windows.Messaging.SendCompletedEventArgs)

        If e.Response = "OLDU" Then MessageBox.Show("olmuş!")

    End Sub

[C#]

        void
MesajGonderici_SendCompleted(object
sender, System.Windows.Messaging.SendCompletedEventArgs e)

        {

            if (e.Response == "OLDU")

            {

                MessageBox.Show("olmuş!");

            }

        }

 

        private void btnGonder_Click(object sender, RoutedEventArgs e)

        {

            System.Windows.Messaging.LocalMessageSender MesajGonderici =

                new
System.Windows.Messaging.LocalMessageSender("MesajKanali", "localhost");

            MesajGonderici.SendCompleted += new EventHandler<System.Windows.Messaging.SendCompletedEventArgs>(MesajGonderici_SendCompleted);

            MesajGonderici.SendAsync("BASLA");

        }

Böylece Silverlight uygulamaları tarafında aynı makinede çalışan, ister
aynı tarayıcıda olsun, ister olmasın farklı domainlerdeki uygulamaların
istenen güvenlik kısıları ile birbiriyle konuşabilmesini sağlamış olduk.
Hem de tüm bunları tamamen istemci tarafında sunucumuzu hiç yormadan
hallettik.

Hepinize kolay gelsin.