2009-06-20 3 views
13

Apple hatte wirklich schlechte Dokumentation darüber, wie der Anbieter sich mit seinem Dienst verbindet und kommuniziert (zum Zeitpunkt des Schreibens - 2009). Ich bin verwirrt über das Protokoll. Wenn jemand da draußen ein C# -Probe zur Verfügung stellen könnte, wäre dies sehr zu begrüßen.Kann jemand einen Apple Push Notification Provider in C# schreiben?

+1

Meiner Meinung nach ist Apples Dokumentation ist ziemlich klar: http://developer.apple.com/iphone/library/documentation/NetworkingInternet/Conceptual/ RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html # // Apple_ref/doc/uid/TP40008194-CH101-SW1 – Linulin

+0

Diese Antwort wurde vor langer Zeit gewählt. Sehen Sie sich auch die Antwort von shay an - http://stackoverflow.com/a/36963561/19854 Wenn Sie nach einem manuellen Weg suchen, um diesen Code zu schreiben, dann schauen Sie sich die ursprünglich gewählte Antwort an: http://stackoverflow.com/a/1077664/19854 – Phobis

Antwort

23

Arbeitscodebeispiel:.

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

Weitere Informationen: http://x-cake.ning.com/profiles/blogs/setting-up-a-push-notification – SteveCav

+0

Welche Sprache ist das? Ich denke, es ist Java, aber Bestätigung benötigt. –

+1

ist es C#, die asp.net ist – Summit

6

Ich hoffe, das ist relevant (leicht), aber ich habe gerade erfolgreich eine für Java, also konzeptionell ganz ähnlich wie C# (außer vielleicht die SSL-Zeug, aber das sollte nicht zu schwer zu ändern. Unten ist ein Beispielnachrichtennutzlast und Krypto-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(); 

}

wieder einmal nicht C#, aber zumindest näher als die Armen ObjC Probe, dass Apple bietet

+0

Ich versuche immer noch, dies zur Arbeit zu bringen. Ich habe Ihren Code in C# dupliziert, aber da .NET eine andere Art von Objekt verwendet, um eine Verbindung über SSL "SSLStream" herzustellen, gibt es keine "Handshake" -Methode. Ich kann nicht herausfinden, wie man den richtigen Handshake zustande bringt. – Phobis

+0

Schauen Sie hier: http://msdn.microsoft.com/en-us/library/system.net.security.sslstream.aspx (etwa drei Viertel der Seite nach unten, gibt es ein C# SSL-Client-Handshake-Beispiel, mit dem SSL-Stream Objekt scheint der Weg zu sein, es zu sehen (ein Rückruf) – Chaos

+0

Dies ist falsch.Es ist nicht ein Server-Socket erstellen.Es schafft einen Client-Socket.TS und Tmf werden manchmal verwendet, um "Trust Store "und" trust manager factory ", aber hier beziehen sie sich auf das Client-Key-Material ... wirklich seltsam. – erickson

2

Das beste APNSSharp Projekt auf Github. Es funktionierte für mich absolut in Ordnung in wenigen Minuten!

1

Sie können die Bibliothek PushSharp in GitHub verwenden.

Ich benutze es in allen meinen Projekten

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

Während dieser Code die Frage beantworten kann, wäre es besser zu erklären, wie es das Problem löst, ohne andere einzuführen und warum es zu verwenden. Nur-Code-Antworten sind auf lange Sicht nicht nützlich. – Mateus

Verwandte Themen