2009-06-20 20 views
13

Apple realmente tenía mala documentación acerca de cómo el proveedor se conecta y se comunica con su servicio (en el momento de la redacción - 2009). Estoy confundido acerca del protocolo. Si alguien por ahí pudiera proporcionar una muestra de C# de cómo se hace esto, sería muy apreciado.¿Alguien sabe cómo escribir un Apple Push Notification Provider en C#?

+1

En mi opinión, la documentación de Apple es bastante claro: http://developer.apple.com/iphone/library/documentation/NetworkingInternet/Conceptual/ RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html # // apple_ref/doc/uid/TP40008194-CH101-SW1 – Linulin

+0

Esta respuesta se eligió hace mucho tiempo. También mire la respuesta de shay - http://stackoverflow.com/a/36963561/19854 Si está buscando una forma manual de escribir este código, mire la respuesta originalmente elegida: http://stackoverflow.com/a/1077664/19854 – Phobis

Respuesta

23

Trabajando ejemplo de código:.

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(); 
+0

más información: http://x-cake.ning.com/profiles/blogs/setting-up-a-push-notification – SteveCav

+0

¿qué idioma es este? Supongo que es Java, pero necesito confirmación. –

+1

es C# que es asp.net – Summit

6

Espero que esto sea relevante (levemente), pero acabo de crear uno exitosamente para Java, conceptualmente bastante similar a C# (excepto tal vez el material SSL, pero eso no debería ser demasiado difícil de modificar. A continuación hay una carga útil y cripto configuración mensaje de muestra:

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(); 

}

Una vez más, no en C#, pero al menos más cerca de los pobres muestra ObjC que Apple ofrece

+0

Todavía estoy tratando de hacer que esto funcione. He duplicado tu código en C#, pero como .NET utiliza un tipo diferente de objeto para conectarse a través de SSL "SSLStream", no tiene un método de "saludo". Parece que no puedo entender cómo lograr el apretón de manos adecuado. – Phobis

+0

Mire aquí: http://msdn.microsoft.com/en-us/library/system.net.security.sslstream.aspx (aproximadamente tres cuartas partes de la página hacia abajo, hay un ejemplo de protocolo de enlace de cliente C# SSL, utilizando el SSLStream objeto. Parece que es la manera de hacerlo, por su aspecto (una devolución de llamada) – Chaos

+0

Esto está mal. No está creando un socket de servidor. Está creando un socket de cliente. Los ts y tmf a veces se usan para referirse a "trust store". "y" fábrica de administrador de confianza ", pero aquí se refieren al material clave del cliente ... realmente extraño. – erickson

2

El mejor proyecto de APNSSharp disponible en Github. ¡Funcionó para mí absolutamente bien en solo unos minutos!

1

Puede usar la biblioteca PushSharp en GitHub.

lo estoy usando en todos mis proyectos

0
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); 
    } 
+0

Si bien este código puede responder la pregunta, sería mejor explicar cómo resuelve el problema sin introducir otros y por qué usarlo. Las respuestas de solo código no son útiles a largo plazo. – Mateus

Cuestiones relacionadas