Makale Özeti

Bu yazımızda Windows Phone 7 ortamında Multitasking işlemlerinin nasıl yapılabileceğine göz atıyoruz.

Makale

Şu ana kadar bildiklerimize dayanarak Windows Phone 7'nin multitasking desteklemeyeceğini rahatlıkla söyleyebiliriz. Bu durum birer yazılım geliştirici olarak çok işimize gelmese de aslında son kullanıcı açısından bunun birçok faydası var. Cihazların pil ömründen tutun performansına kadar çoğu noktada multitasking aslında cebimizde bu minik cihazların kaldıramayacağı bir yük gibi duruyor. Son kullanıcı tarafından baktığımızda sadece kabaca bu duruma iPhone ile herkes alışkın. İşin bir diğer komik yanı ise aslında hiçbir son kullanıcının pek de bu durumu önemsemiyor olması. Yani biz yazılımcılar kadar konuya teknik açıdan bakıp endişelenen pek yok gibi :)

Bir son kullanıcı için önemli olan aslında çalıştırdığı programın arkada çalışıp çalışmadığı bilmekten öte istediği işin yapılıp yapılmadığını veya daha sık karşılaştığımız senaryolarda herhangi bir işin takibinin yapılıp yapılmadığını bilmek. Daha somut bir örnek vermek gerekirse varsayalım ki bir mail istemcisi kullanıyorsunuz. Normalde bilgisayarımızda mail programını açık tutmamızın nedeni mail geldiğinde haberdar olmaktır. Oysa bunun için koca mail programının açık olmasına gerçekten gerek var mı? Yani daha ufak bir yapı arkada mail geldiğinde haberdar olsa da bize ufak bir uyarı mesajı verse? Sonra gerekiyorsa ben mail programını çalıştırıp istediğimi yapsam olmaz mı? İşte Windows Phone 7 içerisinde yer alan PushNotification sistemi de tam olarak bunu çözüyor.

Olayın işleyişine bir göz atalım...

Push mesajlarının gönderiminde toplam üç farklı kimlik bulunuyor diyebiliriz. Bunlardan biri mesajı dinlemede olan telefon, diğeri mesajı gönderen servis, bir diğeri ise iki servisin birbirine ulaşabilmesini sağlayan bir anlamda router görevi gören Microsoft servisi. Her telefon dinleme moduna geçerken bir kanal ismi tanımlayarak kendini "Microsoft Push Notification Service" üzerinde tanımlıyor.

Push Notification Service'inden cihaza özel ulaşım adresi alıyoruz.
Push Notification Service'inden cihaza özel ulaşım adresi alıyoruz.

Yukarıdaki şemada da görebileceğiniz üzere telefon kendi dinleme kanal adı ile servise başvurarak bir adres talep ediyor. Bu adres farklı servislerin telefona push notification gönderirken kullanacakları adres olacak. Böylece rahatlıkla bu adrese sahip her tür yazılım bu adres üzerinden notification gönderebilecek. Söz konusu notification'lar uygulamanız kapalı olsa da işletim sistemi tarafından dinleneceği için uyarılar her zaman kullanıcılara gösterilebilecek. Tabi bu sistemin çalışması için daha önce de bahsettiğimiz üzere bizim de push notificationları sağlayacak bir servise ihtiyacımız var ve bu servisin de telefonun adresine sahip olması gerekiyor.

Push Notification telefona gönderiliyor.
Push Notification telefona gönderiliyor.

İlk aşamada telefon bizim yazacağımız bir servise kendi adresini aktarıyor. Böylece servis artık telefona ulaşabileceği adresi bildiğine göre Push Notification yollmaya hazır. Aslında telefon verdiği adres tam olarak kendi adresi de değil :) Unutmayın bu adres Microsoft Push Notification Service'in verdiği adres. Telefon Microsoft Push Notification Service'den aldığı adresi bizim servise veriyor ve artık bizim servis de bu adrese istediği mesajı gönderiyor. Gönderilen bu mesaj özünde yine Microsoft Push Notification Service'e gidiyor ve Microsoft Push Notification Service'de mesajı telefona iletiyor. Böylece MSPush Notification Service ile cihaz bir Socket bağlantısına sahipken bizim servisimiz sadece istediğinde MS Push Notification Service ile bağlantı kurarak mesaj gönderebiliyor.

Peki nasıl yapacağız bu işleri?

Biz kendi servisimizi temsil etmek üzere bir WPF uygulaması yazalım. Böylece WPF uygulaması kendi içerisinden telefona PUSH mesaj yollayabilir olsun. Uygulamamızın içerisinde telefondan gelecek adres bilgisini alabilecek bir servis olması gerek. Bu servise gelen adrese sonrasında gönderim yaparak telefonu PUSH data yollamış olacağız. 

[VB]

Public Class Service1

    Implements IService1

 

    Public Sub SetURL(ByVal URL As System.Uri) Implements IService1.SetURL

        MainWindow.URL = URL.AbsoluteUri.ToString()

    End Sub

End Class

Gördüğünüz gibi servisimiz epey basit. Tek yaptığı adresi alıp WPF uygulamamızın içerisinde başka bir sınıfta tanımlı shared bir obeye atamak. Herhangi bir sorunla karşılaşmamak adına servisi basicHttpBinding olarak ayarlamanızı tavsiye ederim. Servisin default gelen design adresini kullanarak WP7 uygulamamıza referans olarak ekleyebiliriz hemen. WPF uygulamasında App.Config içerisinde http://localhost:8732/Design_Time_Addresses/WpfApplication1/Service1/ gibi bir adres göreceksiniz. Uygulamamız örnek amaçlı olduğu için doğrudan bu adresi kullanarak WP7 uygulamanıza service reference ekleyebilirsinzi. Tabi onun öncesinde bu servisin host edilmesini de sağlamamız gerek.

[VB]

    Public Shared URL As String

 

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

        Dim SHost As New ServiceHost(GetType(Service1))

        SHost.Open()

    End Sub

İşte bu kadar basit. Uygulamamız açıldığı anda bu servisi host edecek ve böylece bizim WP7 uygulaması da bunu referans alıp kullanabilecek. İsterseniz şimdi de gelin WP7 uygulaması tarafındaki PushNotificationService tanımına bakıp Microsoft Push Notification Service üzerinden adres alıp bizim WPF uygulamasına göndermeye çalışalım.

[C#]

        private void button1_Click(object sender, RoutedEventArgs e)

        {

            var Kanal = new HttpNotificationChannel("UygulamaKanali15");

            Kanal.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(Kanal_ChannelUriUpdated);

            Kanal.Open();

            Kanal.BindToShellNotification();

        }

Kodumuzda yarattığımız HttpNotificationChannel sınıfı Microsoft.Phone.Notification assembly'si altında olduğu için söz konusu DLL'i projeye referans olarak eklemeyi unutmayın. Sonrasında HttpNotificationChannel nesnemizi yaratarak kendi tanımladığımız bir de kanal ismi veriyoruz. Nesnemize ait ChannelUriUpdated event'ı Microsoft Push Notification Service'den cihazın adresi geldiğinde çalışıyor. Özünde biz şu anda hem Push Listener tanımlayıp bunun için Microsoft Push Notification Service'den adres isteyerek elimizdeki Push Notification Service'i de BindToShellNotification ile işletim sistemine aktarıyoruz. Adres geldiğinde söz konusu adresi bizim WPF uygulamasındaki servise aktaracağız.

[C#]

        ServiceReference1.Service1Client Servis = new ServiceReference1.Service1Client();

 

        void Kanal_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)

        {

            Servis.SetURLAsync(e.ChannelUri);

        }

WPF uygulamamızdaki servisi reference aldığımıza göre içerisindeki SetURL metodunu kullanarak ChannelUriUpdated eventinden gelen adresi gönderebiliriz. Böylece WP7 uygulamamız kendi adresini alıp bizim servise göndermiş oldu. Bir sonraki adımda bizim bu adrese yani Microsoft Push Notification Services'a bir mesaj yollamamız gerekiyor ki mesaj telefona iletilsin ve kullanıcıya gösterilsin. Bu nedenle geçiyoruz yine WPF uygulamamıza.

[VB]

        Dim MesajXML = <?xml version="1.0" encoding="utf-8"?>

                       <wp:PushNotification xmlns:wp="WindowsPhonePushNotification">

                           <wp:Toast>

                               <wp:Text1>Mesaj1</wp:Text1>

                               <wp:Text2>Mesaj2</wp:Text2>

                           </wp:Toast>

                       </wp:PushNotification>

 

        Dim Mesaj As String = "X-WindowsPhone-Target: toast" & vbCrLf & vbCrLf & MesajXML.ToString()

Yukarıdaki gördüğünüz XML paketi Microsoft Notification Service'e göndermemiz gereken paket. Bu paketin otomatik hazırlanması ile ilgili bir helper sınıfı eminim ki yakında yayınlanacaktır. Fakat şimdilik elle yapmamız gerekiyor. Paketin içerisinde iki adet String data var. Bu dataları istediğiniz gibi değiştirebilirsiniz. Son olarka hazırladığımız bu paketi daha önce servisimize iletilmiş olan adrese gönderiyoruz.

[VB]

        Dim Gonder As HttpWebRequest = WebRequest.Create(URL)

        Gonder.Method = "POST"

        Gonder.Headers = New WebHeaderCollection()

        Gonder.ContentType = "text/xml"

        Gonder.Headers.Add("X-NotificationClass", "2")

 

        Dim ByteArr = New UTF8Encoding().GetBytes(Mesaj)

        Gonder.ContentLength = ByteArr.Length

        Dim GStream = Gonder.GetRequestStream

        GStream.Write(ByteArr, 0, ByteArr.Length)

ToastNotificaton olarak adlandırılan ve telefonun ekranının üst kısmında bir uyarı olarak çıkan bu mesajlar için üç farklı aciliyet seviyesi belirleyebiliyorsunuz. Yukarıdaki kod içerisinde 2 değeri anında teslimat yapılması gerektiğini belirtliyor. 12 ve 22 gibi değer vererek mesajınızın ToastNotification'lar harici farklı Push Notification mesajları arasında da nasıl önceliklendirilebileceğini belirtebiliyorsunuz. Eh artık herşey hazır. WPF uygulamamızı çalıştırıp WP7 uygulamamızı da başlatabiliriz. WP7 uygulaması ilk olarak Microsoft Notification Services'a bağlanıp kendine bir adres yarattıracak. Sonrasında bu adresi bizim WPF uygulamamıza verecek. WPF uygulamamız da artık istediği zaman bu adres mesaj gönderebilecek. Burada önemli olan nokta telefonda uygulamanız kapalı olsa da mesaj işletim sistemi tarafından alınarak kullanıcıya gösterilebilecek.

ToastNotification sahnede.
ToastNotification sahnede.

Hepinize kolay gelsin.