iPhone Push Notification issue with c#
I cannot send the notification to iphone. Everything seems fine, as the service works out fine, but to message to iphone.
Here is the code:
using (NetworkStream networkStream = client.GetStream())
{
Console.WriteLine("Client connected.");
//X509Certificate clientCertificate = new X509Certificate(@"C:\Users\yagizozturk\Documents\Visual Studio 2010\Projects\GarantiKampanya\Garanti.Web.Service\apns-prod.pem", "");
X509Certificate clientCertificate = new X509Certificate(@"C:\Users\yagizozturk\Documents\Visual Studio 2010\Projects\GarantiKampanya\Garanti.Web.Service\apns-prod-cert.p12", "1234567");
X509CertificateCollection clientCertificateCollection = new X509CertificateCollection(new X509Certificate[1] { clientCertificate });
// Create an SSL stream that will close the client's stream.
SslStream sslStream = new SslStream(
client.GetStream(),
false,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
null
);
try
{
sslStream.AuthenticateAsClient("gateway.sandbox.push.apple.com", clientCertificateCollection, SslProtocols.Default, false);
}
catch (AuthenticationException e)
{
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
client.Close();
return;
}
}
}
string token = "f5aaa8a729613480c79270085e881c435535dac4704dc00b082bfa8fc84aca10";
//string token = "f5aaa8a7 29613480 c7927008 5e881c43 5535dac4 704dc00b 082bfa8f c84aca90";
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] myByteArray = new byte[10000000];
myByteArray = en开发者_如何学编程coding.GetBytes(token);
//int i = 0;
//foreach(char c in token.ToCharArray())
//{
// myByteArray [i] = (byte)c;
// i++;
//}
GeneratePayload(myByteArray, "test", "default");
}
private static byte[] GeneratePayload(byte[] deviceToken, string message, string sound)
{
MemoryStream memoryStream = new MemoryStream();
// Command
memoryStream.WriteByte(0);
byte[] tokenLength = BitConverter.GetBytes((Int16)32);
Array.Reverse(tokenLength);
// device token length
memoryStream.Write(tokenLength, 0, 2);
// Token
memoryStream.Write(deviceToken, 0, 32);
// String length
string apnMessage = string.Format("{{\"aps\":{{\"alert\":{{\"body\":\"{0}\",\"action-loc-key\":null}},\"sound\":\"{1}\"}}}}",
message,
sound);
byte[] apnMessageLength = BitConverter.GetBytes((Int16)apnMessage.Length);
Array.Reverse(apnMessageLength);
// message length
memoryStream.Write(apnMessageLength, 0, 2);
// Write the message
memoryStream.Write(System.Text.ASCIIEncoding.ASCII.GetBytes(apnMessage), 0, apnMessage.Length);
return memoryStream.ToArray();
}
// The following method is invoked by the RemoteCertificateValidationDelegate.
public static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
// Do not allow this client to communicate with unauthenticated servers.
return false;
}
I got the answer. Here is a complete code to send push notifications from c#.
public bool ConnectToAPNS()
{
X509Certificate2Collection certs = new X509Certificate2Collection();
// Add the Apple cert to our collection
certs.Add(getServerCert());
// Apple development server address
string apsHost;
if (getServerCert().ToString().Contains("Production"))
apsHost = "gateway.push.apple.com";
else
apsHost = "gateway.sandbox.push.apple.com";
// Create a TCP socket connection to the Apple server on port 2195
TcpClient tcpClient = new TcpClient(apsHost, 2195);
// Create a new SSL stream over the connection
sslStream = new SslStream(tcpClient.GetStream());
// Authenticate using the Apple cert
sslStream.AuthenticateAsClient(apsHost, certs, SslProtocols.Default, false);
//PushMessage();
return true;
}
private X509Certificate getServerCert()
{
X509Certificate test = new X509Certificate();
//Open the cert store on local machine
X509Store store = new X509Store(StoreLocation.CurrentUser);
if (store != null)
{
// store exists, so open it and search through the certs for the Apple Cert
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certs = store.Certificates;
if (certs.Count > 0)
{
int i;
for (i = 0; i < certs.Count; i++)
{
X509Certificate2 cert = certs[i];
if (cert.FriendlyName.Contains("Apple Production Push Services: KFDLV3XL6Y:ZJPGDMQBKC"))
{
//Cert found, so return it.
return certs[i];
}
}
}
return test;
}
return test;
}
private static byte[] HexToData(string hexString)
{
if (hexString == null)
return null;
if (hexString.Length % 2 == 1)
hexString = '0' + hexString; // Up to you whether to pad the first or last byte
byte[] data = new byte[hexString.Length / 2];
for (int i = 0; i < data.Length; i++)
data[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
return data;
}
public bool PushMessage(string token, string message)
{
String cToken = token;
String cAlert = message;
int iBadge = 1;
// Ready to create the push notification
byte[] buf = new byte[256];
MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
bw.Write(new byte[] { 0, 0, 32 });
byte[] deviceToken = HexToData(cToken);
bw.Write(deviceToken);
bw.Write((byte)0);
// Create the APNS payload - new.caf is an audio file saved in the application bundle on the device
string msg = "{\"aps\":{\"alert\":\"" + cAlert + "\",\"badge\":" + iBadge.ToString() + ",\"sound\":\"new.caf\"}}";
// Write the data out to the stream
bw.Write((byte)msg.Length);
bw.Write(msg.ToCharArray());
bw.Flush();
if (sslStream != null)
{
sslStream.Write(ms.ToArray());
return true;
}
return false;
}
精彩评论