【问题标题】:iPhone Push Notification issue with c#c# 的 iPhone 推送通知问题
【发布时间】:2011-06-01 06:27:27
【问题描述】:

我无法将通知发送到 iPhone。一切似乎都很好,因为服务运行良好,但要向 iphone 发送消息。

代码如下:

using (NetworkStream networkStream = client.GetStream())
            {
                Console.WriteLine("Client connected.");

                //X509Certificate clientCertificate = new X509Certificate(@"C:\Users\yagizozturk\Documents\Visual Studio 2010\Projects\GarantiKampanya\Garanti.Web.Service\apns-prod.pem", "");
                X509Certificate clientCertificate = new X509Certificate(@"C:\Users\yagizozturk\Documents\Visual Studio 2010\Projects\GarantiKampanya\Garanti.Web.Service\apns-prod-cert.p12", "1234567");
                X509CertificateCollection clientCertificateCollection = new X509CertificateCollection(new X509Certificate[1] { clientCertificate });

                // Create an SSL stream that will close the client's stream.
                SslStream sslStream = new SslStream(
                    client.GetStream(),
                    false,
                    new RemoteCertificateValidationCallback(ValidateServerCertificate),
                    null
                    );

                try
                {
                    sslStream.AuthenticateAsClient("gateway.sandbox.push.apple.com", clientCertificateCollection, SslProtocols.Default, false);
                }
                catch (AuthenticationException e)
                {
                    Console.WriteLine("Exception: {0}", e.Message);
                    if (e.InnerException != null)
                    {
                        Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                    }
                    Console.WriteLine("Authentication failed - closing the connection.");
                    client.Close();
                    return;
                }
            }
        }

        string token = "f5aaa8a729613480c79270085e881c435535dac4704dc00b082bfa8fc84aca10";
        //string token = "f5aaa8a7 29613480 c7927008 5e881c43 5535dac4 704dc00b 082bfa8f c84aca90";
        System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();


        byte[] myByteArray = new byte[10000000];

        myByteArray = encoding.GetBytes(token);

        //int i = 0;
        //foreach(char c in token.ToCharArray())
        //{
        //  myByteArray [i] = (byte)c;
        //  i++;
        //}

        GeneratePayload(myByteArray, "test", "default");
    }

    private static byte[] GeneratePayload(byte[] deviceToken, string message, string sound)
    {
        MemoryStream memoryStream = new MemoryStream();

        // Command
        memoryStream.WriteByte(0);

        byte[] tokenLength = BitConverter.GetBytes((Int16)32);
        Array.Reverse(tokenLength);
        // device token length
        memoryStream.Write(tokenLength, 0, 2);

        // Token
        memoryStream.Write(deviceToken, 0, 32);

        // String length
        string apnMessage = string.Format("{{\"aps\":{{\"alert\":{{\"body\":\"{0}\",\"action-loc-key\":null}},\"sound\":\"{1}\"}}}}",
            message,
            sound);

        byte[] apnMessageLength = BitConverter.GetBytes((Int16)apnMessage.Length);
        Array.Reverse(apnMessageLength);
        // message length
        memoryStream.Write(apnMessageLength, 0, 2);

        // Write the message
        memoryStream.Write(System.Text.ASCIIEncoding.ASCII.GetBytes(apnMessage), 0, apnMessage.Length);

        return memoryStream.ToArray();
    }


    // The following method is invoked by the RemoteCertificateValidationDelegate.
    public static bool ValidateServerCertificate(
          object sender,
          X509Certificate certificate,
          X509Chain chain,
          SslPolicyErrors sslPolicyErrors)
    {
        if (sslPolicyErrors == SslPolicyErrors.None)
            return true;

        Console.WriteLine("Certificate error: {0}", sslPolicyErrors);

        // Do not allow this client to communicate with unauthenticated servers.
        return false;
    }

【问题讨论】:

    标签: c# iphone push push-notification


    【解决方案1】:

    我得到了答案。这是从 c# 发送推送通知的完整代码。

        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 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);
    
            //PushMessage();
    
            return true;
        }
    
        private X509Certificate getServerCert()
        {
            X509Certificate test = new X509Certificate();
    
            //Open the cert store on local machine
            X509Store store = new X509Store(StoreLocation.CurrentUser);
    
            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: KFDLV3XL6Y:ZJPGDMQBKC"))
                        {
                            //Cert found, so return it.
                            return certs[i];
                        }
                    }
                }
                return test;
            }
            return test;
        }
    
        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;
        }
    
        public bool PushMessage(string token, string message)
        {
            String cToken = token;
            String cAlert = message;
            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;
        }
    

    【讨论】:

    • 如何将证书添加到 X509Store?你在使用 .pem 文件吗?我似乎无法弄清楚如何将 .pem 文件转换为 X509Certificate
    • 一些 iPhone 开发者给了我 .pem 文件并说它是 APN 所必需的,我如何在这段代码中使用 .pem?
    • @Yagiz Ozturk,我无法执行您的代码,因为 sslStream 在您的答案的当前上下文中不存在,请更新我....
    • 需要特别注意的一点是,您必须使用 .p12 格式而不是 .pem,并且您必须为证书设置密码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多