2009-06-20 9 views
13

Appleは、プロバイダがどのようにサービスに接続して通信しているかについての悪いドキュメントを実際に持っていました(2009年時点)。私はプロトコルについて混乱しています。そこにいる誰かが、これがどのように行われたかのC#サンプルを提供できれば、非常に感謝しています。誰かがApple Push Notification ProviderをC#で書く方法を知っていますか?

+1

でそれを使用しています、Appleのドキュメントはかなり明確である: http://developer.apple.com/iphone/library/documentation/NetworkingInternet/Conceptual/ RemoteNotificationsPG/CommunicatingWithAPS/CommunicatingWithAPS.html#// apple_ref/doc/uid/TP40008194-CH101-SW1 – Linulin

+0

この回答は以前から選択されていました。また、shayからの答えを見てください - http://stackoverflow.com/a/36963561/19854このコードを書く手作業を探しているなら、もともと選んだ答えを見てください:http://stackoverflow.com/a/1077664/19854 – Phobis

答えて

23

操作コード例:

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

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

+0

これはどの言語ですか?私はそれがJavaだと思いますが、確認が必要です。 –

+1

それはasp.netであるC#です – Summit

6

私はこれが適切であることを望みますが、ちょうどJava用のものを作成しましたので、概念的にはC#と非常に似ています(おそらくSSLのものを除きますが、サンプルメッセージペイロードおよび暗号化設定:

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

}

再度、ないC位が、少なくともAppleが提供することが貧弱にObjCサンプルよりも近い

+0

私はまだこれを動作させようとしています。私はあなたのコードをC#で複製しましたが、.NETはSSL "SSLStream"を介して接続するために別の種類のオブジェクトを使用しているので、 "ハンドシェイク"メソッドはありません。私は適切な握手を起こす方法を理解しているようには思えません。 – Phobis

+0

ここをクリックしてください:http://msdn.microsoft.com/en-us/library/system.net.security.sslstream.aspx(ページの約4分の3、C#SSLクライアントハンドシェイクの例があり、SSLStream (コールバック) – Chaos

+0

これは間違っていますそれはサーバーソケットを作成していませんクライアントソケットを作成していますtsとtmfは「信頼ストア"と"トラストマネージャファクトリ "ですが、ここではクライアントキーマテリアルを参照しています...本当に奇妙なものです – erickson

2

最高のAPNSSharpプロジェクトはGithubで利用できます。それはほんの数分で私のために絶対にうまくいった!

1

PushSharpライブラリはGitHubで使用できます。

私は私の意見では私のプロジェクトのすべての

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

このコードは疑問に答えるかもしれませんが、他のものを導入せずにその問題をどのように解決するのか、なぜそれを使用するのか説明する方が良いでしょう。コードのみの回答は長期的には有用ではありません。 – Mateus

関連する問題