iPhone推送通知的问题用C# [英] iPhone Push Notification Problem with c#

查看:258
本文介绍了iPhone推送通知的问题用C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这个话题之前发出,但我同时解决什么是错我的代码实在看不下去清醒。我不能通知发送到iPhone。一切似乎都很好,因为serivice工作了罚款,但消息到iPhone。我需要一个紧急帮助,请。
非常感谢
下面是代码:

 使用(的NetworkStream的NetworkStream = client.GetStream()) 
{
Console.WriteLine(客户端连接。);

// x509证书clientCertificate =新的X509证书(@C:\Users\yagizozturk\Documents\Visual工作室2010\Projects\GarantiKampanya\Garanti.Web.Service\apns -prod.pem,);
x509证书clientCertificate =新的X509证书(@C:\Users\yagizozturk\Documents\Visual工作室2010\Projects\GarantiKampanya\Garanti.Web.Service\apns-PROD-cert.p12 ,1234567);
X509CertificateCollection clientCertificateCollection =新X509CertificateCollection(新的X509Certificate [1] {clientCertificate});

//创建一个SSL数据流,将关闭客户端的数据流。
SslStream sslStream =新SslStream(
client.GetStream(),
假,
新RemoteCertificateValidationCallback(ValidateServerCertificate),

);


{
sslStream.AuthenticateAsClient(gateway.sandbox.push.apple.com,clientCertificateCollection,SslProtocols.Default,FALSE);
}
赶上(的AuthenticationException E)
{
Console.WriteLine(异常:{0},e.Message);
如果(e.InnerException!= NULL)
{
Console.WriteLine(内部异常:{0},e.InnerException.Message);
}
Console.WriteLine(验证失败 - 关闭连接。);
client.Close();
的回报;
}
}
}

字符串标记=f5aaa8a729613480c79270085e881c435535dac4704dc00b082bfa8fc84aca10;
//字符串标记=f5aaa8a7 29613480 c7927008 5e881c43 5535dac4 704dc00b 082bfa8f c84aca90
System.Text.ASCIIEncoding编码=新System.Text.ASCIIEncoding();


字节[] = myByteArray新的字节[千万]

myByteArray = encoding.GetBytes(令牌);

// INT I = 0;
// {
// myByteArray [I] =(字节)C
//的foreach(在token.ToCharArray()字符C);
//我++;
//}

GeneratePayload(myByteArray,测试,默认);
}

私人静态的byte [] GeneratePayload(字节[] deviceToken,字符串消息,串音)
{
的MemoryStream MemoryStream的=新的MemoryStream();

//命令
memoryStream.WriteByte(0);

字节[] = tokenLength BitConverter.GetBytes((Int16的)32);
Array.Reverse(tokenLength);
//设备令牌长度
memoryStream.Write(tokenLength,0,2);

//令牌
memoryStream.Write(deviceToken,0,32);

//字符串长度
串apnMessage =的String.Format({{\aps\:{{\alert\:{{\体\:\{0} \,\行动-LOC-key\:空}},\sound\:\{1} \}}} },
消息,$ b $二声);

字节[] = apnMessageLength BitConverter.GetBytes((Int16的)apnMessage.Length);
Array.Reverse(apnMessageLength);
//消息长度
memoryStream.Write(apnMessageLength,0,2);

//写消息
memoryStream.Write(System.Text.ASCIIEncoding.ASCII.GetBytes(apnMessage),0,apnMessage.Length);

返回memoryStream.ToArray();
}


//以下方法由RemoteCertificateValidationDelegate调用。
公共静态布尔ValidateServerCertificate(
对象发件人,
X509证书证书,
X509Chain链,
SslPolicyErrors sslPolicyErrors)
{
如果(sslPolicyErrors = = SslPolicyErrors.None)
返回真;

Console.WriteLine(证书错误:{0},sslPolicyErrors);

//不要让这个客户与未经认证的服务器通信。
返回FALSE;
}


解决方案

我得到了答案。下面是一个完整的代码从C#发送推送通知。

 公共BOOL ConnectToAPNS()
{
X509Certificate2Collection证书=新X509Certificate2Collection();

//添加苹果证书我们收集
certs.Add(getServerCert());

//苹果开发服务器地址
串apsHost;如果

(。getServerCert()的ToString()包含(生产))
apsHost =gateway.push.apple.com;
,否则
apsHost =gateway.sandbox.push.apple.com;

//创建端口2195
的TcpClient的TcpClient =新的TcpClient(apsHost,2195)TCP套接字连接到苹果服务器;

//创建连接上的
sslStream =新SslStream一个新的SSL流(tcpClient.GetStream());

//身份验证使用Apple证书
sslStream.AuthenticateAsClient(apsHost,证书,SslProtocols.Default,FALSE);

// PushMessage();

返回真;
}

私人x509证书getServerCert()
{
x509证书考试=新的X509Certificate();

//打开本地计算机上的
的X509Store店=新的X509Store(StoreLocation.CurrentUser)的证书存储;

如果(店!= NULL)
{
//店存在,所以打开它,并通过证书为苹果证书
store.Open搜索(OpenFlags 。只读);
X509Certificate2Collection证书= store.Certificates;

如果(certs.Count大于0)
{
INT I;
为(i = 0; I< certs.Count;我++)
{
X509Certificate2证书=证书[I]

如果(cert.FriendlyName.Contains(苹果生产推送服务:KFDLV3XL6Y:ZJPGDMQBKC))
{
//证书找到,因此将其返回。
返回证书[I]
}
}
}
返回测试;
}
返回测试;
}

私人静态的byte [] HexToData(字符串十六进制串)
{
如果(十六进制串== NULL)
返回NULL;

如果(hexString.Length%2 == 1)
十六进制串='0'+十六进制串; //取决于你是否垫的第一个或最后一个字节

字节[]数据=新字节[hexString.Length / 2];

的for(int i = 0; I< data.Length;我++)
数据[I] = Convert.ToByte(hexString.Substring(我* 2,2),16) ;

返回数据;
}

公共BOOL PushMessage(字符串标记,字符串消息)
{
字符串cToken =记号。
字符串cAlert =消息;
INT iBadge = 1;

//准备创建推送通知
的byte [] buf中=新的字节[256];
的MemoryStream毫秒=新的MemoryStream();
的BinaryWriter体重=新的BinaryWriter(毫秒);
bw.Write(新字节[] {0,0,32});

字节[] = deviceToken HexToData(cToken);
bw.Write(deviceToken);

bw.Write((字节),0);

//创建APNS有效载荷 - new.caf是保存在设备
string信息的应用程序包的音频文件={\aps\:{\ alert\:\+ cAlert +\,\badge\:+ iBadge.ToString()+,\sound\:\new.caf \}};

//将数据写入到流
bw.Write((字节)msg.Length);
bw.Write(msg.ToCharArray());
bw.Flush();

如果(sslStream!= NULL)
{
sslStream.Write(ms.ToArray());
返回真;
}

返回FALSE;
}


I knew this topic is issued before but i really could not stand awake while solving what is wrong with my code. I cannot send the notification to iphone. Everything seems fine, as the serivice works out fine, but to message to iphone. I need an urgent help please. Thanks alot Here is the code :

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;
    }

解决方案

I got the answer. Here is a complete code to send push notifications from 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;
    }

这篇关于iPhone推送通知的问题用C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆