30

我试图用 C# 为 iPhone 编写一个推送服务器。我有以下代码:

        // Create a TCP/IP client socket.
        using (TcpClient client = new TcpClient())
        {
            client.Connect("gateway.sandbox.push.apple.com", 2195);
            using (NetworkStream networkStream = client.GetStream())
            {
                Console.WriteLine("Client connected.");

                X509Certificate clientCertificate = new X509Certificate(@"certfile.p12", passwordHere);
                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");
                }
                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;
                }
            }

等等……

只有我不断收到异常:“对 SSPI 的调用失败,请参阅内部异常”内部异常 - >“收到的消息是意外的或格式错误。”

有谁知道这里出了什么问题?

4

6 回答 6

8

弄清楚了。替换 sslStream.AuthenticateAsClient("gateway.sandbox.push.apple.com"); 使用 sslStream.AuthenticateAsClient("gateway.sandbox.push.apple.com", clientCertificateCollection, SslProtocols.Default, false); 并在 PC 上注册证书。

编辑:这是根据要求创建有效负载的代码:

    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();
    } // End of GeneratePayload
于 2009-07-23T22:16:58.490 回答
5

来自 Zenox 的评论:使用不同版本的 AuthenticateAsClient

sslStream.AuthenticateAsClient("gateway.sandbox.push.apple.com", clientCertificateCollection, SslProtocols.Default, false);
于 2009-07-16T19:42:22.927 回答
1

其他方法就是使用 X509Certificate2 和 X509CertificateCollection2 类。

于 2009-07-03T03:27:59.350 回答
1

我最近使用Growl For Windows将消息从 .Net 代码推送到 iPhone 上的 Prowl 客户端。因此,您无需自己编写推送服务器即可获得您的功能。

于 2009-07-11T22:03:09.300 回答
0

“收到的消息意外或格式错误。” 当您没有在 Windows 中注册 p12 证书时,通常会出现错误。(在Vista下,只需双击p12文件即可打开导入向导)

于 2009-07-16T12:13:27.377 回答
0

在我的情况下,我必须从我的 Windows 8 中删除所有证书,然后重新安装它们才能将推送通知发送到苹果设备。

我不知道为什么我的证书停止工作,我正在寻找正确的原因,很快就会在这里更新。

于 2013-11-28T07:26:15.237 回答