How to write an Apple Push Notification Provider in C#?

梦想与她 提交于 2019-11-27 10:32:26
shader

Working code example:

int port = 2195;
String hostname = "gateway.sandbox.push.apple.com";

//load certificate
string certificatePath = @"cert.p12";
string certificatePassword = "";
X509Certificate2 clientCertificate = new X509Certificate2(certificatePath, certificatePassword);
X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);

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

try
{
    sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, true);
}
catch (AuthenticationException ex)
{
    client.Close();
    return;
}

// Encode a test message into a byte array.
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)

String deviceId = "DEVICEIDGOESHERE";
writer.Write(ToByteArray(deviceId.ToUpper()));

String payload = "{\"aps\":{\"alert\":\"I like spoons also\",\"badge\":14}}";

writer.Write((byte)0); //First byte of payload length; (big-endian first byte)
writer.Write((byte)payload.Length); //payload length (big-endian second byte)

byte[] b1 = System.Text.Encoding.UTF8.GetBytes(payload);
writer.Write(b1);
writer.Flush();

byte[] array = memoryStream.ToArray();
sslStream.Write(array);
sslStream.Flush();

// Close the client connection.
client.Close();

I hope this is relevant (slightly), but I have just successfully created one for Java, so conceptually quite similar to C# (except perhaps the SSL stuff, but that shouldn't be too hard to modify. Below is a sample message payload and crypto setup:

    int port = 2195;
    String hostname = "gateway.sandbox.push.apple.com";


    char []passwKey = "<keystorePassword>".toCharArray();
    KeyStore ts = KeyStore.getInstance("PKCS12");
    ts.load(new FileInputStream("/path/to/apn_keystore/cert.p12"), passwKey);

    KeyManagerFactory tmf = KeyManagerFactory.getInstance("SunX509");
    tmf.init(ts,passwKey);
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(tmf.getKeyManagers(), null, null);
    SSLSocketFactory factory =sslContext.getSocketFactory();
    SSLSocket socket = (SSLSocket) factory.createSocket(hostname,port); // Create the ServerSocket
    String[] suites = socket.getSupportedCipherSuites();
    socket.setEnabledCipherSuites(suites);
    //start handshake

    socket.startHandshake();


    // Create streams to securely send and receive data to the server
    InputStream in = socket.getInputStream();
    OutputStream out = socket.getOutputStream();



    // Read from in and write to out...
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    baos.write(0); //The command
    System.out.println("First byte Current size: " + baos.size());

    baos.write(0); //The first byte of the deviceId length    
    baos.write(32); //The deviceId length

    System.out.println("Second byte Current size: " + baos.size());

    String deviceId = "<heaxdecimal representation of deviceId";
    baos.write(hexStringToByteArray(deviceId.toUpperCase()));
    System.out.println("Device ID: Current size: " + baos.size());


    String payload = "{\"aps\":{\"alert\":\"I like spoons also\",\"badge\":14}}";
    System.out.println("Sending payload: " + payload);
    baos.write(0); //First byte of payload length;
    baos.write(payload.length());
    baos.write(payload.getBytes());

    out.write(baos.toByteArray());
    out.flush();

    System.out.println("Closing socket..");
    // Close the socket
    in.close();
    out.close();

}

Once again, not C#, but at least closer than the poor ObjC sample that Apple provides.

The best APNSSharp project available on Github. It worked for me absolutely fine in just couple of minutes!

You can use the PushSharp library in GitHub.

I am using it in all of my projects

  public ActionResult ios()
    {
        string message = string.Empty;

        var certi = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Certificates2.p12");
        var appleCert = System.IO.File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Certificates2.p12"));

        ApnsConfiguration apnsConfig = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Production, appleCert, "Password");

        var apnsBroker = new ApnsServiceBroker(apnsConfig);
        apnsBroker.OnNotificationFailed += (notification, aggregateEx) =>
        {
            aggregateEx.Handle(ex =>
            {
                if (ex is ApnsNotificationException)
                {
                    var notificationException = (ApnsNotificationException)ex;
                    var apnsNotification = notificationException.Notification;
                    var statusCode = notificationException.ErrorStatusCode;
                    var inner = notificationException.InnerException;
                    message = "IOS Push Notifications: Apple Notification Failed: ID=" + apnsNotification.Identifier + ", Code=" + statusCode + ", Inner Exception" + inner;
                }
                else
                {
                    message = "IOS Push Notifications: Apple Notification Failed for some unknown reason : " + ex.InnerException;
                }
                return true;
            });
        };

        apnsBroker.OnNotificationSucceeded += (notification) =>
        {
            message = "IOS Push Notifications: Apple Notification Sent!";
        };

        apnsBroker.Start();
        try
        {
            string deviceToken = "33c2f3a13c90dc62660281913377c22066c1567e23c2ee2c728e0f936ff3ee9b";

            apnsBroker.QueueNotification(new ApnsNotification
            {
                DeviceToken = deviceToken,
                Payload = JObject.Parse("{\"aps\":{\"alert\":\" Test Message\", \"badge\":1, \"sound\":\" default\",}}")
            });
        }
        catch (Exception ex)
        {
            Console.Write(ex);
        }
        apnsBroker.Stop();

        return View(message);
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!