Apple push notification server side in C#
Asked Answered
G

2

7

I'm new to .net and doing apn server side in C#. I'm using below code to push the messages to apple server.

    private void pushMessage()
    {
        int port = 2195;
        String deviceID = "4564c705 63b371aa 3811699e 1e4ac3d2 ba592b27 f2a5a613 d25cd035 xx213e54";
        String hostname = "gateway.sandbox.push.apple.com";     // TEST
        //String hostname = "gateway.push.apple.com";           // REAL

        //        @"cert.p12";
        String certificatePath = HttpContext.Current.Server.MapPath("Certi.p12");
        //X509Certificate2 clientCertificate = new X509Certificate2(certificatePath, "");

        X509Certificate2 clientCertificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

        X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
        TcpClient client = new TcpClient(hostname, port);

        // _apnsStream = new SslStream(_apnsClient.GetStream(), false, validateServerCertificate, SelectLocalCertificate);
        //SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate),null);

        SslStream sslStream = new SslStream(client.GetStream(), false, validateServerCertificate, SelectLocalCertificate);
        try
        {
            sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Default, false);
        }
        catch (Exception e)
        {
            throw (e);
            client.Close();
            return;
        }

        MemoryStream memoryStream = new MemoryStream();
        BinaryWriter writer = new BinaryWriter(memoryStream);
        writer.Write((byte)0);  //The command
        writer.Write((byte)0);  //The first byte of the deviceId length (big-endian first byte)
        writer.Write((byte)32); //The deviceId length (big-endian second byte)

        writer.Write(HexStringToByteArray(deviceID.ToUpper()));
        String payload = "{\"aps\":{\"alert\":\"hello\",\"badge\":0,\"sound\":\"default\"}}";
        writer.Write((byte)0);
        writer.Write((byte)payload.Length);
        byte[] b1 = System.Text.Encoding.UTF8.GetBytes(payload);
        writer.Write(b1);
        writer.Flush();
        byte[] array = memoryStream.ToArray();
        sslStream.Write(array);
        sslStream.Flush();
        client.Close();
    }

    private string HexStringToByteArray(string p)
    {
        throw new NotImplementedException();
    }

In execution, getting error like "A call to SSPI failed, see inner exception".

enter image description here

enter image description here

I'm doing any wrong or missed here. Any certificate installation is required in windows? Please help me.

Gracielagracile answered 28/1, 2013 at 8:47 Comment(4)
You need to click on View Detail... and tell us what the inner exception details are. You also have a few issues with your code - such as your catch is useless - all it will do is lose your stack trace and any code after throw(e) will not be executed (to name a couple).Indigestive
Take a look at #1885459. The OP provides an answer for how they fixed the same issue.Indigestive
I would strongly suggest to use PushSharp as they have working examples that you can simply take and use...Confucianism
You know that your exception handler is faulty, right? The client will never be closed, as throw(e); performs an immediated exit from the exception handler, thus the following two lines will never be called and the exception will be bubbled up.Pelagia
G
2

I changed my code in PushNotification.class file

_certificate = string.IsNullOrEmpty(p12FilePassword)? new X509Certificate2(File.ReadAllBytes(p12File)): new X509Certificate2(File.ReadAllBytes(p12File), p12FilePassword);

with

_certificate = string.IsNullOrEmpty(p12FilePassword) ? new X509Certificate2(File.ReadAllBytes(p12File)) : new X509Certificate2(File.ReadAllBytes(p12File), p12FilePassword, X509KeyStorageFlags.MachineKeySet);
Gracielagracile answered 6/5, 2013 at 10:41 Comment(0)
D
-2

so try....

SslStream sslStream = new SslStream(client.GetStream(), false,
    new RemoteCertificateValidationCallback(ValidateServerCertificate), null);

....

public static bool ValidateServerCertificate(object sender,
                                             X509Certificate certificate,
                                             X509Chain chain,
                                             SslPolicyErrors sslPolicyErrors)
{
  if (sslPolicyErrors == SslPolicyErrors.None)
    return true;

  gerarLog("Certificate error: " + sslPolicyErrors);

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

public static byte[] HexStringToByteArray(string hexString)
{
  byte[] HexAsBytes = new byte[hexString.Length / 2];
  for (int index = 0; index < HexAsBytes.Length; index++)
  {
    string byteValue = hexString.Substring(index * 2, 2);
    HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
  }
  return HexAsBytes;
}
Drachma answered 5/1, 2016 at 20:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.