Setting up a Push Notification service on Windows Server 2003
2012-09-11 19:23
537 查看
转自:http://x-cake.ning.com/profiles/blogs/setting-up-a-push-notification
Setting up a Push Notification service on Windows Server 2003
For this tutorial, I will be using IIS 6, SQL Server Express, and ASP.net (coded in CSharp).
I’m assuming you know how to set up and use SQL, IIS and ASP.net.
I've put up a good few code samples to get you started as well. I'm not sure if this info is still under NDA now that 3.0 is out, so I may have to remove it again if Apple don't like it.
It’s recommended that you run a service with a persistent connection to APNS.
I found a good tutorial on Windows Services and managed to write one up in a couple of
hours. You can use the code from below in your service (the new site doesn't seem to like code formatting. If anyone know of a better tag to get tabs and syntax highlighting, let me know).
Install SQL and ASP.net if you haven’t already done so and set up your site in IIS.
In SQL, you’ll need to store (at minimum) the unique device token that your app generates when it runs. This isn’t a fixed token and can change (e.g. on device restore) so be sure to record it each time the app is run. I tie the device token
to an account ID, but you could just as easily tie it to the UDID in the database.
Getting Started with Certs
In the iPhone Developer Program Portal create a new explicit App ID (com.mycompany.MyApp) and enable push for both Development & Production. This will generate two SSL Certs, which you should download and add to your login keychain.
Next, open Keychain Access and locate the two certs. Command-click on each cert and Export as .p12.
Upload both .p12 files to your server. If you double-click the two files, this will install them into the Current User’s Certificate Store. This is fine for testing, but you’ll want to store them in the Local Computer store if you want it to
work properly as a service.
Run MMC and add the Certificates snap-in, select Computer Account, then hit Finish on the next page. Hit OK to view the new snap-in.
Expand the Certificates (Local Computer) snap-in and right-click on Personal. Select All Tasks -> Import from the context menu. Locate your .p12 files and add them to the store.
Next, we need to allow the ASP.net service account access to these certs. I had a bit of trouble with this, but found doing all of the following worked:
where MyCertificate is the “Apple Production Push Services: ABCDEFGHIJ:KLMNOPQRST” text.
Make sure that you fully open ports 2195 (push server) and 2196 (feedback service) on your firewall.
Getting the Device Token in your iPhone App
Coding the ASP.net / Windows Service
In your ASP.net code, you’ll need to open a secure socket connection to the APNS server - either gateway.sandbox.push.apple.com (development sandbox) or gateway.push.apple.com (production) on port 2195.
If you’ve signed your app using the Development provisioning profile, then it will only receive notifications sent to the sandbox server. Similarly, Production profiles only receive from the production server.
It’s recommended that you leave the socket open for as long as possible and just send push notifications as required:
Feedback Service
Make sure that you check the feedback service at least every hour to remove any user tokens owned by users who have uninstalled your app:
My feedback service code isn’t fully functional yet, so check out this hint on the developer forums:
https://devforums.apple.com/message/85206#85206
Note: when testing this, you’ll need at least one other Push app installed on your device, otherwise the service will never know that your app has been uninstalled.
Setting up a Push Notification service on Windows Server 2003
For this tutorial, I will be using IIS 6, SQL Server Express, and ASP.net (coded in CSharp).
I’m assuming you know how to set up and use SQL, IIS and ASP.net.
I've put up a good few code samples to get you started as well. I'm not sure if this info is still under NDA now that 3.0 is out, so I may have to remove it again if Apple don't like it.
It’s recommended that you run a service with a persistent connection to APNS.
I found a good tutorial on Windows Services and managed to write one up in a couple of
hours. You can use the code from below in your service (the new site doesn't seem to like code formatting. If anyone know of a better tag to get tabs and syntax highlighting, let me know).
Install SQL and ASP.net if you haven’t already done so and set up your site in IIS.
In SQL, you’ll need to store (at minimum) the unique device token that your app generates when it runs. This isn’t a fixed token and can change (e.g. on device restore) so be sure to record it each time the app is run. I tie the device token
to an account ID, but you could just as easily tie it to the UDID in the database.
Getting Started with Certs
In the iPhone Developer Program Portal create a new explicit App ID (com.mycompany.MyApp) and enable push for both Development & Production. This will generate two SSL Certs, which you should download and add to your login keychain.
Next, open Keychain Access and locate the two certs. Command-click on each cert and Export as .p12.
Upload both .p12 files to your server. If you double-click the two files, this will install them into the Current User’s Certificate Store. This is fine for testing, but you’ll want to store them in the Local Computer store if you want it to
work properly as a service.
Run MMC and add the Certificates snap-in, select Computer Account, then hit Finish on the next page. Hit OK to view the new snap-in.
Expand the Certificates (Local Computer) snap-in and right-click on Personal. Select All Tasks -> Import from the context menu. Locate your .p12 files and add them to the store.
Next, we need to allow the ASP.net service account access to these certs. I had a bit of trouble with this, but found doing all of the following worked:
a) To grant access to ASPNET account: winhttpcertcfg -g -c LOCAL_MACHINE\MY -s MyCertificate -a ASPNET b) To grant access to Network Service: winhttpcertcfg -g -c LOCAL_MACHINE\MY -s MyCertificate -a "Network Service" c) To grant access to Authenticated Users: winhttpcertcfg -g -c LOCAL_MACHINE\MY -s MyCertificate -a "Authenticated Users"
where MyCertificate is the “Apple Production Push Services: ABCDEFGHIJ:KLMNOPQRST” text.
Make sure that you fully open ports 2195 (push server) and 2196 (feedback service) on your firewall.
Getting the Device Token in your iPhone App
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)]; // launchOptions contains aps data (NSDictionary) if app was launched from notification alert if (launchOptions) { if ([launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"]) { if ([[launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"] objectForKey:@"aps"]) { NSLog(@"Received Notification (Launch): %@", [launchOptions objectForKey:@"aps"]); } } } } // Called if registration is successful -(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { // Store the device token in your online DB // ... } // Called if we fail to register for a device token - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"Error in registration. Error: %@", error); } // Called if notification is received while app is active - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSLog(@"Received Notification (Active): %@", userInfo); }
Coding the ASP.net / Windows Service
In your ASP.net code, you’ll need to open a secure socket connection to the APNS server - either gateway.sandbox.push.apple.com (development sandbox) or gateway.push.apple.com (production) on port 2195.
If you’ve signed your app using the Development provisioning profile, then it will only receive notifications sent to the sandbox server. Similarly, Production profiles only receive from the production server.
// Get the APNS cert private X509Certificate getServerCert() { // Open the cert store on the Local Machine X509Store store = new X509Store(StoreLocation.LocalMachine); if (store != null) { // Store exists, so open it and search through the certs for the Apple cert store.Open(OpenFlags.ReadOnly); X509Certificate2Collection certs = store.Certificates; if (certs.Count > 0) { int i; for (i = 0; i < certs.Count; i++) { X509Certificate2 cert = certs[i]; if (cert.FriendlyName.Contains("Apple Production Push Services: ABCDEFGHIJ:KLMNOPQRST"))) { // Cert found, so return it return certs[i]; } } } return null; } // Make the connection to the APNS server public bool ConnectToAPNS() { X509Certificate2Collection certs = new X509Certificate2Collection(); // Add the Apple cert to our collection certs.Add(getServerCert()); // Apple development server address string apsHost; if (getServerCert().ToString().Contains("Production")) apsHost = "gateway.push.apple.com"; else apsHost = "gateway.sandbox.push.apple.com"; // Create a TCP socket connection to the Apple server on port 2195 tcpClient = new TcpClient(apsHost, 2195); // Create a new SSL stream over the connection sslStream = new SslStream(tcpClient.GetStream()); // Authenticate using the Apple cert sslStream.AuthenticateAsClient(apsHost, certs, SslProtocols.Default, false); }
It’s recommended that you leave the socket open for as long as possible and just send push notifications as required:
// Used to convert device token from string to byte[] private static byte[] HexToData(string hexString) { if (hexString == null) return null; if (hexString.Length % 2 == 1) hexString = '0' + hexString; // Up to you whether to pad the first or last byte byte[] data = new byte[hexString.Length / 2]; for (int i = 0; i < data.Length; i++) data[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return data; } // Push a Hello World message to the device public bool PushMessage() { String cToken = "yourdevicetoken...." String cAlert = "Hello World!"; int iBadge = 1; // Ready to create the push notification byte[] buf = new byte[256]; MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); bw.Write(new byte[] { 0, 0, 32 }); byte[] deviceToken = HexToData(cToken); bw.Write(deviceToken); bw.Write((byte)0); // Create the APNS payload - new.caf is an audio file saved in the application bundle on the device string msg = "{\"aps\":{\"alert\":\"" + cAlert + "\",\"badge\":" + iBadge.ToString() + ",\"sound\":\"new.caf\"}}"; // Write the data out to the stream bw.Write((byte)msg.Length); bw.Write(msg.ToCharArray()); bw.Flush(); if (sslStream != null) { sslStream.Write(ms.ToArray()); return true; } return false; }
Feedback Service
Make sure that you check the feedback service at least every hour to remove any user tokens owned by users who have uninstalled your app:
My feedback service code isn’t fully functional yet, so check out this hint on the developer forums:
https://devforums.apple.com/message/85206#85206
// Required because SSL connection cannot be established due to invalid cert warning. public static bool ValidateServerCertificate(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true } public String CheckFeedbackService() { System.Net.ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate); // Create an empty collection of certs X509Certificate2Collection certs = new X509Certificate2Collection(); // Add the Apple cert to our collection certs.Add(getServerCert()); // Apple feedback server address string apsHostF; if (getServerCert().ToString().Contains("Production")) apsHostF = "feedback.push.apple.com"; else apsHostF = "feedback.sandbox.push.apple.com"; // Create a TCP socket connection to the Apple server on port 2196 TcpClient tcpClientF = new TcpClient(apsHostF, 2196); // Create a new SSL stream over the connection SslStream sslStreamF = new SslStream(tcpClientF.GetStream(), true, new RemoteCertificateValidationCallback(ValidateServerCertificate)); try { // Authenticate using the Apple cert sslStreamF.AuthenticateAsClient(apsHostF, certs, SslProtocols.Default, false); //TODO: Read in data and remove device tokens if any found. if (sslStreamF != null) sslStreamF.Close(); if (tcpClientF != null) tcpClientF.Close(); } catch (AuthenticationException e) { Console.WriteLine("Authentication failed - closing the connection."); sslStreamF.Close(); tcpClientF.Close(); return "NOAUTH"; } finally { // The client stream will be closed with the sslStream // because we specified this behavior when creating // the sslStream. sslStreamF.Close(); tcpClientF.Close(); } return ""; }
Note: when testing this, you’ll need at least one other Push app installed on your device, otherwise the service will never know that your app has been uninstalled.
相关文章推荐
- Setting up SSL with a SelfSSL certificate on Windows Server 2003
- Setting up SFTP on Windows Server 2008 R2
- 转:Setting up a Msysgit Server with copSSH on Windows
- Windows 2003 Server: Background Intelligent Transfer Service service hung on starting异常
- Installing UrlRewriter.NET on Windows Server 2003
- Installing an SSH Server on Windows 2003
- 【转】《基于MFC的OpenGL编程》Part 2 Setting up OpenGL on Windows(1)
- Setting Up A PXE Install Server For Multiple Linux Distributions and WinPE On Debian Lenny
- You cannot access the existing File Share resources on a Windows Server 2003 failover cluster
- Setting up a Subversion Server on Ubuntu Gutsy Gibbon server
- windows安装mysql的坑:ERROR 2003 (HY000): Can’t connect to MySQL server on ‘localhost’ (10061)
- set up SMTP server on Windows 2008[备忘]
- 【转】《基于MFC的OpenGL编程》Part 2 Setting up OpenGL on Windows(2)
- Setting up a EDK II build environment on Windows and Linux:搭建Windows和Linux开发环境[2.2]
- Setting up a CloudStack dev environment on Windows
- Q: #6 Is the Feature Builder Preview supported on Windows XP and Windows Server 2003?
- Setting Up the Development Environment for SharePoint 2010 on Windows Vista,
- 《基于MFC的OpenGL编程》Part 2 Setting up OpenGL on Windows
- 《基于MFC的OpenGL编程》Part 2 Setting up OpenGL on Windows