@@ -39,146 +39,146 @@ Here are couple of links to provide guidance (from Windows Dev Center) -
39
39
40
40
9 . Make sure you are calling the following method at the app startup. Configure your * Notification Hub name* and the * DefaultListenSharedAccessSignature* .
41
41
42
- public async void RegisterToReceiveNotifications()
43
- {
44
- string notificationHubName = "[hubName]";
45
- string connectionString = "[ConnectionString-DefaultListenSharedAccessSignature]";
46
-
47
- // Register with WNS
48
- var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
49
-
50
- // Register with Azure Notification Hubs
51
- NotificationHub hub = new NotificationHub(notificationHubName, connectionString);
52
- hub.Register(channel.Uri);
53
- Debug.WriteLine("ChannelURI : {0}", channel.Uri);
54
- }
42
+ public async void RegisterToReceiveNotifications()
43
+ {
44
+ string notificationHubName = "[hubName]";
45
+ string connectionString = "[ConnectionString-DefaultListenSharedAccessSignature]";
46
+
47
+ // Register with WNS
48
+ var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
49
+
50
+ // Register with Azure Notification Hubs
51
+ NotificationHub hub = new NotificationHub(notificationHubName, connectionString);
52
+ hub.Register(channel.Uri);
53
+ Debug.WriteLine("ChannelURI : {0}", channel.Uri);
54
+ }
55
55
56
56
10 . Add a Notification Hub class which abstracts the functionality of registering with the Azure Notification Hubs. This is based on [ Notification Hubs REST APIs] . See explanation in the following steps:
57
57
58
- class NotificationHub
59
- {
60
- private const string ApiVersion = "?api-version=2014-09";
61
- private const string AuthHeader = "Authorization";
62
- private const string ContentType = "application/atom+xml;type=entry;charset=utf-8";
63
-
64
- static string HubName { get; set; }
65
- static string ConnectionString { get; set; }
66
- static string Endpoint { get; set; }
67
- static string SasKeyName { get; set; }
68
- static string SasKeyValue { get; set; }
69
- static string Payload { get; set; }
70
-
71
- public NotificationHub(string hubName, string connectionString)
72
- {
73
- HubName = hubName;
74
- ConnectionString = connectionString;
75
- }
76
-
77
- public void Register(string pushChannel)
78
- {
79
- ParseConnectionInfo();
80
- SendNHRegistrationRequest(pushChannel);
81
- }
82
-
83
- // From http://msdn.microsoft.com/en-us/library/dn495627.aspx
84
- private static void ParseConnectionInfo()
85
- {
86
- if (string.IsNullOrWhiteSpace(HubName))
87
- {
88
- throw new InvalidOperationException("Hub name is empty");
89
- }
90
-
91
- var parts = ConnectionString.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
92
-
93
- if (parts.Length != 3)
94
- {
95
- throw new InvalidOperationException("Error parsing connection string: " + ConnectionString);
96
- }
97
-
98
- foreach (var part in parts)
99
- {
100
- if (part.StartsWith("Endpoint"))
101
- {
102
- Endpoint = "https" + part.Substring(11);
103
- }
104
- else if (part.StartsWith("SharedAccessKeyName"))
105
- {
106
- SasKeyName = part.Substring(20);
107
- }
108
- else if (part.StartsWith("SharedAccessKey"))
109
- {
110
- SasKeyValue = part.Substring(16);
111
- }
112
- }
113
- }
114
- private static string GenerateSaSToken(Uri uri)
115
- {
116
- var targetUri = WebUtility.UrlEncode(uri.ToString().ToLower()).ToLower();
117
-
118
- var expiresOnDate = Convert.ToInt64(DateTime.UtcNow.Subtract
119
- (new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds) + 60 * 60;
120
- var toSign = targetUri + "\n" + expiresOnDate;
121
-
122
- var keyBytes = Encoding.UTF8.GetBytes(SasKeyValue);
123
- var mac = new HMACSHA256(keyBytes);
124
- mac.Initialize();
125
- var rawHmac = mac.ComputeHash(Encoding.UTF8.GetBytes(toSign));
126
- var signature = WebUtility.UrlEncode(Convert.ToBase64String(rawHmac));
127
-
128
- var token = "SharedAccessSignature sr=" + targetUri + "&sig="
129
- + signature + "&se=" + expiresOnDate + "&skn=" + SasKeyName;
130
- return token;
131
- }
132
-
133
- private static void SendNHRegistrationRequest(string pushChannel)
134
- {
135
- Payload =
136
- @"<?xml version=""1.0"" encoding=""utf-8""?>
137
- <entry xmlns=""http://www.w3.org/2005/Atom"">
138
- <content type=""application/xml"">
139
- <WindowsRegistrationDescription xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.microsoft.com/netservices/2010/10/servicebus/connect"">
140
- <ChannelUri>{WindowsPushChannel}</ChannelUri>
141
- </WindowsRegistrationDescription >
142
- </content>
143
- </entry>";
144
-
145
- Payload = Payload.Replace("{WindowsPushChannel}", pushChannel);
146
-
147
- var uri = new Uri(Endpoint + HubName + "/registrations/" + ApiVersion);
148
- var sendRequest = WebRequest.CreateHttp(uri);
149
- sendRequest.Method = "POST";
150
- sendRequest.ContentType = ContentType;
151
- sendRequest.Headers[AuthHeader] = GenerateSaSToken(uri);
152
- sendRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), sendRequest);
153
- }
154
-
155
- static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
156
- {
157
- HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
158
- // End the stream request operation
159
- Stream postStream = request.EndGetRequestStream(asynchronousResult);
160
-
161
- byte[] byteArray = Encoding.UTF8.GetBytes(Payload);
162
-
163
- postStream.Write(byteArray, 0, byteArray.Length);
164
- postStream.Close();
165
-
166
- //Start the web request
167
- request.BeginGetResponse(new AsyncCallback(GetResponceStreamCallback), request);
168
- }
169
-
170
- static void GetResponceStreamCallback(IAsyncResult callbackResult)
171
- {
172
- HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
173
- HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
174
- using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
175
- {
176
- string result = httpWebStreamReader.ReadToEnd();
177
- //For debug: show results
178
- Debug.WriteLine(result);
179
- }
180
- }
181
- }
58
+ class NotificationHub
59
+ {
60
+ private const string ApiVersion = "?api-version=2014-09";
61
+ private const string AuthHeader = "Authorization";
62
+ private const string ContentType = "application/atom+xml;type=entry;charset=utf-8";
63
+
64
+ static string HubName { get; set; }
65
+ static string ConnectionString { get; set; }
66
+ static string Endpoint { get; set; }
67
+ static string SasKeyName { get; set; }
68
+ static string SasKeyValue { get; set; }
69
+ static string Payload { get; set; }
70
+
71
+ public NotificationHub(string hubName, string connectionString)
72
+ {
73
+ HubName = hubName;
74
+ ConnectionString = connectionString;
75
+ }
76
+
77
+ public void Register(string pushChannel)
78
+ {
79
+ ParseConnectionInfo();
80
+ SendNHRegistrationRequest(pushChannel);
81
+ }
82
+
83
+ // From http://msdn.microsoft.com/en-us/library/dn495627.aspx
84
+ private static void ParseConnectionInfo()
85
+ {
86
+ if (string.IsNullOrWhiteSpace(HubName))
87
+ {
88
+ throw new InvalidOperationException("Hub name is empty");
89
+ }
90
+
91
+ var parts = ConnectionString.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
92
+
93
+ if (parts.Length != 3)
94
+ {
95
+ throw new InvalidOperationException("Error parsing connection string: " + ConnectionString);
96
+ }
97
+
98
+ foreach (var part in parts)
99
+ {
100
+ if (part.StartsWith("Endpoint"))
101
+ {
102
+ Endpoint = "https" + part.Substring(11);
103
+ }
104
+ else if (part.StartsWith("SharedAccessKeyName"))
105
+ {
106
+ SasKeyName = part.Substring(20);
107
+ }
108
+ else if (part.StartsWith("SharedAccessKey"))
109
+ {
110
+ SasKeyValue = part.Substring(16);
111
+ }
112
+ }
113
+ }
114
+ private static string GenerateSaSToken(Uri uri)
115
+ {
116
+ var targetUri = WebUtility.UrlEncode(uri.ToString().ToLower()).ToLower();
117
+
118
+ var expiresOnDate = Convert.ToInt64(DateTime.UtcNow.Subtract
119
+ (new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds) + 60 * 60;
120
+ var toSign = targetUri + "\n" + expiresOnDate;
121
+
122
+ var keyBytes = Encoding.UTF8.GetBytes(SasKeyValue);
123
+ var mac = new HMACSHA256(keyBytes);
124
+ mac.Initialize();
125
+ var rawHmac = mac.ComputeHash(Encoding.UTF8.GetBytes(toSign));
126
+ var signature = WebUtility.UrlEncode(Convert.ToBase64String(rawHmac));
127
+
128
+ var token = "SharedAccessSignature sr=" + targetUri + "&sig="
129
+ + signature + "&se=" + expiresOnDate + "&skn=" + SasKeyName;
130
+ return token;
131
+ }
132
+
133
+ private static void SendNHRegistrationRequest(string pushChannel)
134
+ {
135
+ Payload =
136
+ @"<?xml version=""1.0"" encoding=""utf-8""?>
137
+ <entry xmlns=""http://www.w3.org/2005/Atom"">
138
+ <content type=""application/xml"">
139
+ <WindowsRegistrationDescription xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.microsoft.com/netservices/2010/10/servicebus/connect"">
140
+ <ChannelUri>{WindowsPushChannel}</ChannelUri>
141
+ </WindowsRegistrationDescription >
142
+ </content>
143
+ </entry>";
144
+
145
+ Payload = Payload.Replace("{WindowsPushChannel}", pushChannel);
146
+
147
+ var uri = new Uri(Endpoint + HubName + "/registrations/" + ApiVersion);
148
+ var sendRequest = WebRequest.CreateHttp(uri);
149
+ sendRequest.Method = "POST";
150
+ sendRequest.ContentType = ContentType;
151
+ sendRequest.Headers[AuthHeader] = GenerateSaSToken(uri);
152
+ sendRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), sendRequest);
153
+ }
154
+
155
+ static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
156
+ {
157
+ HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
158
+ // End the stream request operation
159
+ Stream postStream = request.EndGetRequestStream(asynchronousResult);
160
+
161
+ byte[] byteArray = Encoding.UTF8.GetBytes(Payload);
162
+
163
+ postStream.Write(byteArray, 0, byteArray.Length);
164
+ postStream.Close();
165
+
166
+ //Start the web request
167
+ request.BeginGetResponse(new AsyncCallback(GetResponceStreamCallback), request);
168
+ }
169
+
170
+ static void GetResponceStreamCallback(IAsyncResult callbackResult)
171
+ {
172
+ HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
173
+ HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
174
+ using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
175
+ {
176
+ string result = httpWebStreamReader.ReadToEnd();
177
+ //For debug: show results
178
+ Debug.WriteLine(result);
179
+ }
180
+ }
181
+ }
182
182
183
183
11 . ` ParseConnectionInfo ` & ` GenerateSaSToken ` are used to create the standard Authorization header you need to communicate with Azure Notification Hubs.
184
184
0 commit comments