Reputation: 767
I'm creating one web api application, and I want to send notification to iOS devices.
I've tried with pushsharp, but it works fine with few devices only, while sending it to multiple devices with expired/invalid tokens its not sending notifications to all devices.
So, I'm going with following code:
public async Task pushMessage(string deviceToken, string message)
{
int port = 2195;
String hostname = "gateway.sandbox.push.apple.com";
String certificatePath = "~/test.p12" // my certificate path
X509Certificate2 clientCertificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), CommonSource.GetAppleCertificatePassword(), X509KeyStorageFlags.MachineKeySet);
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, false);
MemoryStream memoryStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memoryStream);
writer.Write((byte)0);
writer.Write((byte)0);
writer.Write((byte)32);
writer.Write(HexStringToByteArray(deviceToken.ToUpper()));
String payload = message.ToString();
writer.Write((byte)0);
writer.Write((byte)payload.Length);
byte[] b1 = System.Text.Encoding.UTF8.GetBytes(payload);
writer.Write(b1);
writer.Flush();
byte[] array = memoryStream.ToArray();
sslStream.Write(array);
sslStream.Flush();
// Read message from the server.
//byte[] response = ReadMessage(sslStream);
client.Close();
}
catch (System.Security.Authentication.AuthenticationException ex)
{
LogError(ex.Message);
client.Close();
}
catch (Exception e)
{
LogError(e.Message);
client.Close();
}
}
This code works exactly what I wanted.
But now I want to check response from APNS server. So I've checked with byte[] response = ReadMessage(sslStream);
And ReadMessage method looks like:
private byte[] ReadMessage(SslStream sslStream)
{
MemoryStream ms = new MemoryStream();
byte[] buffer = new byte[1024];
int bytes = -1;
do
{
bytes = sslStream.Read(buffer, 0, buffer.Length);
ms.Write(buffer, 0, bytes);
} while (bytes != 0);
return ms.ToArray();
}
But when I run this, it stuck at bytes = sslStream.Read(buffer, 0, buffer.Length);
I'm not able to figure out the issue.
Can anyone tell me, what is the issue with my code?
Upvotes: 3
Views: 2441
Reputation: 247153
According to this article
The problem with Apples Push Notification Service… Solutions and Workarounds…
Apple never sends a response for messages that succeeded.
An error response may not immediately be returned before you have a chance to send more notifications to the stream, but before Apple closes the connection. These notifications that might still ‘make it through’ are left in limbo. They are never acknowledged or delivered, and never have error responses returned for them.
So in a case where your request works as intended there will be no response. That would mean that your attempt to read a response will not get anything and this is what you are experiencing when you can't get past the read line. It is waiting for a response that might never come.
Upvotes: 5