Невозможно отправить сообщение APNS с сертификатом распространения
Я установил и успешно протестировал обмен сообщениями APNS с сертификатом разработки и gateway.sandbox.push.apple.com
,
Когда я перехожу на свой сертификат распространения и gateway.push.apple.com
сообщения не проходят, и я получаю исключение:
Невозможно записать данные в транспортное соединение: установленное соединение было прервано программным обеспечением на вашем хост-компьютере.
Я следовал этим учебникам, чтобы сгенерировать сертификат p12:
http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1 http://code.google.com/p/apns-sharp/wiki/HowToCreatePKCS12Certificate
Серверное программное обеспечение, от которого я отправляю уведомления, является приложением.NET, использующим SslStream
а также X509Certificate2
классы.
Ниже приведен код подключения:
/// <summary>
/// Establish connection to Apple's Push Notification System using the variables in the config file.
/// </summary>
public void ConnectToAPNS()
{
try
{
int port = Convert.ToInt32(Config.SSL_PORT ); // 2195
// pick the target address
String hostname = Config.SSL_PATH; // gateway.push.apple.com
//load certificate
string certificatePath = Config.CERT_FILE; //.p12 certification file
string certificatePassword = Config.CERT_PASS;
byte[] p12Data = System.IO.File.ReadAllBytes(certificatePath);
X509Certificate2 clientCertificate = new X509Certificate2(p12Data, certificatePassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
X509Certificate2Collection certificatesCollection = new X509Certificate2Collection();
certificatesCollection.Add(clientCertificate);
RemoteCertificateValidationCallback remote = new RemoteCertificateValidationCallback(ValidateServerCertificate);
client = new TcpClient(hostname, port);
sslStream = new SslStream(
client.GetStream(),
false,
remote,
null
);
try
{
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, true);
}
catch (AuthenticationException e)
{
IQLogger.Logger.LogError("Push NotifyMessenger ConnectToAPNS: " + e.Message);
client.Close();
sslStream = null;
client = null;
return;
}
}catch (Exception e)
{
IQLogger.Logger.LogError("PushNotifyMessenger ConnectToAPNS: " + e.Message);
sslStream = null;
client = null;
return;
}
return;
}
/// <summary>
/// Call back checks for validation error
/// </summary>
/// <returns></returns>
public static bool ValidateServerCertificate( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
try{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
}
catch
{
}
IQLogger.Logger.LogError("PushNotifyMessenger ValidateServerCertificate: sslPolicyErrors" + sslPolicyErrors);
// Do not allow this client to communicate with unauthenticated servers.
return false;
}
Это код для отправки сообщения:
/// <summary>
/// I send a text message to a specified device ID. I provide an example of how to format a message for the APNS system.
/// The message must be formatted in Json and be sent as a byte array.
/// </summary>
/// <param name="deviceId"> A string containing 64 characters representing hexidecimal values of a 32 byte device code</param>
/// <param name="msgPrompt">The text that will popup on the device </param>
/// <param name="msgData"> XML that will be put in the XML json Section. This data will be invisible to the recipient's user,
/// but will be accessible by the recipient program</param>
public void SendMessage(string deviceId, string msgPrompt, string msgData)
{
try{
if (client == null || sslStream == null)
{
ConnectToAPNS();
}
// 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)
byte[] arDeviceID = ConvertDeviceID(deviceId);//System.Text.Encoding.UTF8.GetBytes(deviceId);
writer.Write(arDeviceID);
String payload = "{\"aps\":{\"alert\":\"" + msgPrompt + "\",\"badge\":1,\"xml\":\"" + msgData + "\"}}";
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); // <<<<<<<<<< exception thrown here
sslStream.Flush();
}
catch (Exception e)
{
IQLogger.Logger.LogError("PushNotifyMessenger.SendMessage: " + e.Message);
return;
}
}
Исключение выдается при 2-й или 3-й попытке отправить сообщение APNS. Однако ни одно из сообщений никогда не поступает на устройство. Я могу вернуться к своему сертификату разработки, и этот код работает нормально (и сообщения APNS поступают на устройство).
В поисках решения проблемы я обнаружил сообщения о том, что сертификат разработки каким-то образом мешает развертыванию, однако я не понимаю, как это происходит, и что я должен сделать для его решения.
Заранее благодарим за любую помощь, которую вы можете предоставить.
1 ответ
Убедитесь, что вы используете APNS Live URL сервера ssl://gateway.push.apple.com:2195