APNS反馈服务C#代码无效

时间:2014-07-09 05:03:12

标签: c# asp.net-mvc apple-push-notifications apns-sharp

我尝试实施我在here找到的反馈服务代码。

这是我的代码:

private X509Certificate getServerCert(string certName)
        {
            var store = new X509Store(StoreLocation.LocalMachine);
            try
            {
                store.Open(OpenFlags.ReadOnly);
                var certs = store.Certificates.Find(X509FindType.FindBySubjectName, certName, false);
                return certs.Count == 0 ? null : certs[0];
            }
            finally
            {
                store.Close();
            }
        }

public String CheckFeedbackService(string certaName)
        {

            System.Net.ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
            KIREIP.Core.Manager.IphoneErrorLog errorLog = new KIREIP.Core.Manager.IphoneErrorLog();
            // Create an empty collection of certs
            X509Certificate2Collection certs = new X509Certificate2Collection();

            // Add the Apple cert to our collection
            certs.Add(getServerCert(certaName));

            // Apple feedback server address
            string apsHostF;

            if (getServerCert(certaName).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);

            //Set up
            byte[] buffer = new byte[38];
            int recd = 0;
            DateTime minTimestamp = DateTime.Now.AddYears(-1);
            string result = string.Empty;

            // 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.
                errorLog.AddErrorLog("Stream Readable ::" + sslStreamF.CanRead);
                //errorLog.AddErrorLog("Host Name ::" + hostName);
                errorLog.AddErrorLog("Cert Name ::" + certs[0].FriendlyName);

                if (sslStreamF != null)
                {
                    errorLog.AddErrorLog("Connection Started");

                    //Get the first feedback
                    recd = sslStreamF.Read(buffer, 0, buffer.Length);
                    errorLog.AddErrorLog("Buffer length ::" + recd);
                    //Continue while we have results and are not disposing
                    while (recd > 0)
                    {

                        errorLog.AddErrorLog("Reading Started");
                        //Get our seconds since 1970 ?
                        byte[] bSeconds = new byte[4];
                        byte[] bDeviceToken = new byte[32];
                        Array.Copy(buffer, 0, bSeconds, 0, 4);
                        //Check endianness
                        if (BitConverter.IsLittleEndian)
                            Array.Reverse(bSeconds);
                        int tSeconds = BitConverter.ToInt32(bSeconds, 0);
                        //Add seconds since 1970 to that date, in UTC and then get it locally
                        var Timestamp = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(tSeconds).ToLocalTime();
                        //Now copy out the device token
                        Array.Copy(buffer, 6, bDeviceToken, 0, 32);
                        string deviceToken = BitConverter.ToString(bDeviceToken).Replace("-", "").ToLower().Trim();
                        //Make sure we have a good feedback tuple
                        if (deviceToken.Length == 64 && Timestamp > minTimestamp)
                        {
                            errorLog.AddErrorLog("Feedback " + deviceToken);
                            result = deviceToken;
                            errorLog.AddErrorLog(result);
                        }
                        //Clear  array to reuse it
                        Array.Clear(buffer, 0, buffer.Length);
                        //Read the next feedback
                        recd = sslStreamF.Read(buffer, 0, buffer.Length);
                    }
                    errorLog.AddErrorLog("Reading Ended");
                }

                if (sslStreamF != null)
                    sslStreamF.Close();

                if (tcpClientF != null)
                    tcpClientF.Close();

            }

            catch (AuthenticationException e)
            {
                errorLog.AddErrorLog("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 "";
        }

每当我运行此代码时,我从getServerCert(certName)方法获取null值,因为这个空值我的进一步执行失败。

非常感谢任何帮助

1 个答案:

答案 0 :(得分:0)

我使用JdSoft.Apns.Feedback.dll我找到了here(或者您可以直接谷歌获取最新版本)。

使用此.dll我已生成以下方法,包含2个代表

public string CheckFeedBack()
        {

            //Variables you may need to edit:
            //---------------------------------
            //Log.AddErrorLog("Start");
            //True if you are using sandbox certificate, or false if using production
            bool sandbox = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["sandbox"].ToString());

            //Put your PKCS12 .p12 or .pfx filename here.
            // Assumes it is in the same directory as your app
            string p12File = System.Configuration.ConfigurationManager.AppSettings["p12File"].ToString();

            //This is the password that you protected your p12File 
            //  If you did not use a password, set it as null or an empty string
            string p12FilePassword = System.Configuration.ConfigurationManager.AppSettings["p12FilePassword"].ToString();


            //Actual Code starts below:
            //--------------------------------

            //Get the filename assuming the file is in the same directory as this app
            string p12Filename = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, p12File);
            //errorLog.AddErrorLog(p12Filename);
            //Create the feedback service consumer
            FeedbackService service = new FeedbackService(sandbox, p12Filename, p12FilePassword);

            //Wireup the events
            service.Error += new FeedbackService.OnError(service_Error);
            service.Feedback += new FeedbackService.OnFeedback(service_Feedback);

            //Run it.  This actually connects and receives the feedback
            // the Feedback event will fire for each feedback object
            // received from the server
            service.Run();
            Log.AddErrorLog("Done.");
            Log.AddErrorLog("Cleaning up...");

            //Clean up
            service.Dispose();

            return "Checked database table log..";
        } 

代表连接反馈和错误事件

            static void service_Feedback(object sender, Feedback feedback)
            {
             Log.AddErrorLog(string.Format("Feedback - Timestamp: {0} - DeviceId: {1}", feedback.Timestamp, feedback.DeviceToken));
             //DeviceToken retrive over here

            }
            static void service_Error(object sender, Exception ex)
            {

             Log.AddErrorLog(string.Format("Error: {0}", ex.Message));
             //Error Message if failed
            }