This is a Sample push notification .
Here I am trying to give an Idea What activities going behind in Push Notification .
1)Windows phone :-
Here we need to writing the code for to generate Uri .
This Uri generate by MPNS with the help Push Client (it is part of Windows Phone OS activity)
What and Why Uri ?
What/ Why ans is for unique Communication establish Device(windows phone) to Server( Cloud Service provider)
This Uri Unique one for Every application in windows phone . it was generating the combination of application name and OS .
==================================================================
private const string ChannelName = "TestNotification";
private void SetupNotificationChannel()
{
_channel = HttpNotificationChannel.Find(ChannelName);
if (_channel == null)
{
_channel = new HttpNotificationChannel(ChannelName);
_channel.ChannelUriUpdated += ChannelUriUpdated;
_channel.ErrorOccurred += (s, e) => Deployment.Current.Dispatcher.BeginInvoke(() => ErrorOccurred(e));
_channel.Open();
}
else
{
RegisterForNotifications();
}
}
========================================================================
the above method checking the channelname if it is not existed the channelname we need create channel for this application and Updates Uri with the help of MPNS .
Step 1:- Creating a web/WCF Service to Send the message to Register clients.
Now i am going to create a WCF service :-
interface IService1 is like below:-
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
namespace TestWCFNotification
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
void Subscribe(Guid uniqID, string uri);
[OperationContract]
void SendToastNotification(string title,string message);
// TODO: Add your service operations here
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
}
and Implementation is :-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Net;
namespace TestWCFNotification
{
//Notification Types
public enum NotificationType
{
Tile = 1,
Toast = 2,
Raw = 3
}
//Time interval required to send messages.
public enum BatchingInterval
{
TileImmediately = 1,
ToastImmediately = 2,
RawImmediately = 3,
//TileWait450 = 11,
//ToastWait450 = 12,
//RawWait450 = 13,
//TileWait900 = 21,
//ToastWait900 = 22,
//RawWait900 = 23
}
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
public class Service1 : IService1
{
private static Dictionary<Guid, Uri> _clientUris = new Dictionary<Guid, Uri>();
public void Subscribe(Guid uniqID, string uri)
{
if (_clientUris.ContainsKey(uniqID))
{
_clientUris[uniqID] = new Uri(uri);
}
else
{
_clientUris.Add(uniqID, new Uri(uri));
}
}
public void SendToastNotification(string title ,string message)
{
var toastMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<wp:Notification xmlns:wp=\"WPNotification\">" +
"<wp:Toast>" +
"<wp:Text1>" + title + "</wp:Text1>" +
"<wp:Text2>" + message + "</wp:Text2>" +
"</wp:Toast>" +
"</wp:Notification>";
toastMessage = string.Format(toastMessage, message);
var messageBytes = System.Text.Encoding.UTF8.GetBytes(toastMessage);
foreach (var uri in _clientUris.Values)
{
SendMessage(uri, messageBytes, NotificationType.Toast);
}
}
public void SendRawNotification(string message)
{
var messageBytes = Encoding.UTF8.GetBytes(message);
foreach (var uri in _clientUris.Values)
{
SendMessage(uri, messageBytes, NotificationType.Raw);
}
}
private void SendMessage(Uri uri, byte[] messageBytes, NotificationType notificationType)
{
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = WebRequestMethods.Http.Post;
request.ContentType = "text/xml";
request.ContentLength = messageBytes.Length;
request.Headers.Add("X-MessageID", Guid.NewGuid().ToString());
if (notificationType == NotificationType.Toast)
{
request.Headers["X-WindowsPhone-Target"] = "toast";
request.Headers.Add("X-NotificationClass", ((int)BatchingInterval.ToastImmediately).ToString());
}
else
{
request.Headers.Add("X-NotificationClass", ((int)BatchingInterval.RawImmediately).ToString());
}
using (var requestStream = request.GetRequestStream())
{
requestStream.Write(messageBytes, 0, messageBytes.Length);
}
}
}
}
Webconfig file ( You may get some time out exception so make sure ur web config file has this type of configuration :-
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicBinding" closeTimeout="10:01:00" openTimeout="10:01:00" receiveTimeout="10:20:00" sendTimeout="10:01:00"
maxBufferSize="2147483647" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647">
<readerQuotas maxDepth="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" maxStringContentLength="2147483647" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="TestWCFNotification.Service1"
name="TestWCFNotification.Service1">
<endpoint address=""
binding="basicHttpBinding" bindingConfiguration="BasicBinding"
contract="TestWCFNotification.IService1">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://19x.16x.x.xx//TestNotification/Service1.svc" />
</baseAddresses>
</host>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<!--<behavior>-->
<!--To avoid disclosing metadata information, set the values below to false before deployment-->
<behavior name="TestWCFNotification.Service1">
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceThrottling maxConcurrentCalls="20" maxConcurrentSessions="20"
maxConcurrentInstances="2147483647" />
<!--</behavior>-->
</behavior>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<!--To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information-->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>-->
<!--<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />-->
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Note :- Change Localhost to ur IP address for this u need to host in the IIS .Otherwise Windows Phone it won't accept ur service .
Step 2:-
Here i am Writing code for simple and sample Windows Phone application.
What ever getting result is added to this listbox .if application is not open just show the notification alert to end user .
MainPage.Xaml :-
========================================================================
<phone:PhoneApplicationPage
x:Class="TestNotificationWP8.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="Push Notification" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0" FontSize="30"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="200"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="1" x:Name="lstOffers" BorderBrush="Azure" BorderThickness="5" Margin="10,10,10,10" Height="200">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontFamily="Segoe WP Light" FontSize="20"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
========================================================================
Here MainPage.xaml.cs :-
using System;
using System.Linq;
using System.Windows;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Notification;
using System.ComponentModel;
using System.IO.IsolatedStorage;
using System.Diagnostics;
using System.IO;
namespace TestNotificationWP8
{
public partial class MainPage : PhoneApplicationPage
{
private HttpNotificationChannel _channel;
private const string ChannelName = "TestNotification";
private Guid _deviceId;
// Constructor
public MainPage()
{
InitializeComponent();
if (DesignerProperties.IsInDesignTool)
return;
if (IsolatedStorageSettings.ApplicationSettings.Contains("DeviceId"))
{
_deviceId = (Guid)IsolatedStorageSettings.ApplicationSettings["DeviceId"];
}
else
{
_deviceId = Guid.NewGuid();
IsolatedStorageSettings.ApplicationSettings["DeviceId"] = _deviceId;
}
SetupNotificationChannel();
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
private void SetupNotificationChannel()
{
_channel = HttpNotificationChannel.Find(ChannelName);
if (_channel == null)
{
_channel = new HttpNotificationChannel(ChannelName);
_channel.ChannelUriUpdated += ChannelUriUpdated;
_channel.ErrorOccurred += (s, e) => Deployment.Current.Dispatcher.BeginInvoke(() => ErrorOccurred(e));
_channel.Open();
}
else
{
RegisterForNotifications();
}
}
private void RegisterForNotifications()
{
RegisterWithNotificationService();
_channel.ShellToastNotificationReceived += (s, e) => Deployment.Current.Dispatcher.BeginInvoke(() => ToastReceived(e));
_channel.HttpNotificationReceived += (s, e) => Deployment.Current.Dispatcher.BeginInvoke(() => HttpNotificationReceived(e));
_channel.ErrorOccurred += (s, e) => Deployment.Current.Dispatcher.BeginInvoke(() => ErrorOccurred(e));
}
private void RegisterWithNotificationService()
{
var svc = new ServiceReference1.Service1Client();
svc.SubscribeCompleted += (s, e) =>
{
if (e.Error != null)
{
Debug.WriteLine("Error registering with notification service");
}
};
svc.SubscribeAsync(_deviceId, _channel.ChannelUri.ToString());
}
private void HttpNotificationReceived(HttpNotificationEventArgs e)
{
var reader = new StreamReader(e.Notification.Body);
var message = reader.ReadToEnd();
lstOffers.Items.Add("Raw notification : " + message);
reader.Close();
}
private void ToastReceived(NotificationEventArgs e)
{
// lstOffers.Items.Add("Toast Recevied : " + e.Collection["wp:Text1"]);
lstOffers.Items.Add( "Toast Recevied : "+ String.Format("Title:" + e.Collection["wp:Text1"] + "\nMessage:" + e.Collection["wp:Text2"]));
}
private void ErrorOccurred(NotificationChannelErrorEventArgs e)
{
lstOffers.Items.Add(e.Message);
Debug.WriteLine("ERROR:" + e.Message);
}
private void ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
_channel = HttpNotificationChannel.Find(ChannelName);
if (!_channel.IsShellToastBound)
{
_channel.BindToShellToast();
}
RegisterForNotifications();
}
}
}
===========================================================
and Ur WCF Service Reference to Windows phone 8 , i have given name with ServiceReference1
and i have created client line below
var svc = new ServiceReference1.Service1Client();
Step 3 Server application It needs to send the message to register Clients :-
Above window.xaml page :-
==================================================================
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" closeTimeout="10:10:00"
openTimeout="10:10:00" receiveTimeout="10:10:00" sendTimeout="10:10:00"
maxReceivedMessageSize="2147483647" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://19x.16x.x.xx/TestNotification/Service1.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" />
</client>
</system.serviceModel>
</configuration>
========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfPushNotification
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
ServiceReference1.Service1Client SvcClient = new ServiceReference1.Service1Client();
if (txtMessage.Text != string.Empty)
{
SvcClient.SendToastNotification("Tester", txtMessage.Text);
}
else
{
MessageBox.Show("Pls Provide Message to Send");
}
//{
// MessageBox.Show("Sent successful");
//}
//else
//{
// MessageBox.Show(" not Sent");
//}
}
}
}
For this we need to add service Reference and i given named as ServiceReference1 .
Step 4 :-
Need to host WCf in IIS .
Step 5 :- Need to check Service Reference in Windows or WPF and Windows phone application .
Step 6:- Need to Run the Windows application then come to home page
step 7 :- Run the Windows/WpF application provide some message in Text box like below:-
Step 8 u r message will be display like below in windows phone :-
No comments:
Post a Comment