推送通知中的生产证书错误 - PushSharp
Production certificate error in push notification - PushSharp
当我在生产环境中使用具有以下推送通知证书的企业帐户时,我的应用程序收到推送通知:
Apple 生产 iOS 推送服务
然后为了在 App store 中发布我的应用程序,我开始使用 app store 帐户,无论我尝试什么,apple 都会以以下名称创建生产证书:
Apple 推送服务
然后从这个SO,我知道Apple已经更改了证书中的命名。我的问题是,我在服务器端使用 Push Sharp 并出现以下错误:
You have selected the Production server, yet your Certificate does not
appear to be the Production certificate! Please check to ensure you
have the correct certificate!
中给出的两种解决方案均无效。
我将 Push Sharp 从 2.2 更新到 3.0 beta,遇到很多编译错误,甚至 PushSharp class 本身也不存在,然后尝试了该线程的另一个解决方案。
从 this 下载 PushSharp 并通过删除生产线重新编译它,仍然出现相同的错误。另外那个解决方案不是很清楚,我不确定是否要评论证书检查行还是什么,我试过了但没有运气
如何解决这个问题?
您可以开始使用新的 PushSharp 3.0.1 稳定版,它非常简单而且很棒。
首先,您应该转到并删除所有与 pushsharp 2 相关的 dll:
- PushSharp.Core
- PushSharp.Apple
- PushSharp.Android
等也确保删除:
- Newtonsoft.Json.dll(会产生冲突,我会解释)
然后转到您的项目并打开 nuget 管理器,然后搜索 PushSharp 3 的最新稳定版本并下载它。
现在您应该使用新的 Pushsharp 3 API,它略有不同但更简单:
首先创建一个class,其中包含您想要的所有经纪人:
public class AppPushBrokers
{
public ApnsServiceBroker Apns { get; set; }
public GcmServiceBroker Gcm { get; set; }
public WnsServiceBroker wsb { get; set; }
}
然后在您的业务逻辑/控制器/ViewModel 等方面,您需要编写您的 PushNotification 业务:
public class NewPushHandler
{
#region Constants
public const string ANDROID_SENDER_AUTH_TOKEN = "xxxx";
public const string WINDOWS_PACKAGE_NAME = "yyyy";
public const string WINDOWS_PACKAGE_SECURITY_IDENTIFIER = "zzzz";
public const string WINDOWS_CLIENT_SECRET = "hhhh";
public const string APPLE_APP_NAME = "yourappname";
public const string APPLE_PUSH_CERT_PASS = "applecertpass";
#endregion
#region Private members
bool useProductionCertificate;
string appleCertificateType;
String appleCertName;
String appleCertPath;
byte[] appCertData;
// logger
ILogger logger;
// Config (1- Define Config for each platform)
ApnsConfiguration apnsConfig;
GcmConfiguration gcmConfig;
WnsConfiguration wnsConfig;
#endregion
#region Constructor
public NewPushHandler()
{
// Initialize
useProductionCertificate = true; // you can set it dynamically from config
appleCertificateType = useProductionCertificate == true ? "production.p12" : "development.p12";
appleCertName = APPLE_APP_NAME + "-" + appleCertificateType;
appleCertPath = Path.Combine(Application.StartupPath, "Crt", appleCertName); // for web you should use HttpContext.Current.Server.MapPath(
appCertData = File.ReadAllBytes(appleCertPath);
var appleServerEnv = ApnsConfiguration.ApnsServerEnvironment.Production;
logger = LoggerHandler.CreateInstance();
// 2- Initialize Config
apnsConfig = new ApnsConfiguration(appleServerEnv, appCertData, APPLE_PUSH_CERT_PASS);
gcmConfig = new GcmConfiguration(ANDROID_SENDER_AUTH_TOKEN);
wnsConfig = new WnsConfiguration(WINDOWS_PACKAGE_NAME, WINDOWS_PACKAGE_SECURITY_IDENTIFIER, WINDOWS_CLIENT_SECRET);
}
#endregion
#region Private Methods
#endregion
#region Public Methods
public void SendNotificationToAll(string msg)
{
// 3- Create a broker dictionary
var apps = new Dictionary<string, AppPushBrokers> { {"com.app.yourapp",
new AppPushBrokers {
Apns = new ApnsServiceBroker (apnsConfig),
Gcm = new GcmServiceBroker (gcmConfig),
wsb = new WnsServiceBroker(wnsConfig)
}}};
#region Wire Up Events
// 4- events to fires onNotification sent or failure for each platform
#region Android
apps["com.app.yourapp"].Gcm.OnNotificationFailed += (notification, aggregateEx) =>
{
aggregateEx.Handle(ex =>
{
// See what kind of exception it was to further diagnose
if (ex is GcmConnectionException)
{
// Something failed while connecting (maybe bad cert?)
Console.WriteLine("Notification Failed (Bad APNS Connection)!");
}
else
{
Console.WriteLine("Notification Failed (Unknown Reason)!");
}
// Mark it as handled
return true;
});
};
apps["com.app.yourapp"].Gcm.OnNotificationSucceeded += (notification) =>
{
//log success here or do what ever you want
};
#endregion
#region Apple
apps["com.app.yourapp"].Apns.OnNotificationFailed += (notification, aggregateEx) =>
{
aggregateEx.Handle(ex =>
{
// See what kind of exception it was to further diagnose
if (ex is ApnsNotificationException)
{
var apnsEx = ex as ApnsNotificationException;
// Deal with the failed notification
var n = apnsEx.Notification;
logger.Error("Notification Failed: ID={n.Identifier}, Code={apnsEx.ErrorStatusCode}");
}
else if (ex is ApnsConnectionException)
{
// Something failed while connecting (maybe bad cert?)
logger.Error("Notification Failed (Bad APNS Connection)!");
}
else
{
logger.Error("Notification Failed (Unknown Reason)!");
}
// Mark it as handled
return true;
});
};
apps["com.app.yourapp"].Apns.OnNotificationSucceeded += (notification) =>
{
Console.WriteLine("Notification Sent!");
};
#endregion
#endregion
#region Prepare Notification
// 5- prepare the json msg for android and ios and any platform you want
string notificationMsg = msg;
string jsonMessage = @"{""message"":""" + notificationMsg +
@""",""msgcnt"":1,""sound"":""custom.mp3""}";
string appleJsonFormat = "{\"aps\": {\"alert\":" + '"' + notificationMsg + '"' + ",\"sound\": \"default\"}}";
#endregion
#region Start Send Notifications
// 6- start sending
apps["com.app.yourapp"].Apns.Start();
apps["com.app.yourapp"].Gcm.Start();
//apps["com.app.yourapp"].wsb.Start();
#endregion
#region Queue a notification to send
// 7- Queue messages
apps["com.app.yourapp"].Gcm.QueueNotification(new GcmNotification
{
// You can get this from database in real life scenarios
RegistrationIds = new List<string> {
"ppppp",
"nnnnn"
},
Data = JObject.Parse(jsonMessage),
Notification = JObject.Parse(jsonMessage)
});
apps["com.app.yourapp"].Apns.QueueNotification(new ApnsNotification
{
DeviceToken = "iiiiiii",
Payload = JObject.Parse(appleJsonFormat)
});
#endregion
#region Stop Sending Notifications
//8- Stop the broker, wait for it to finish
// This isn't done after every message, but after you're
// done with the broker
apps["com.app.yourapp"].Apns.Stop();
apps["com.app.yourapp"].Gcm.Stop();
//apps["com.app.yourapp"].wsb.Stop();
#endregion
}
#endregion
}
重要提示:
有时特别是当您使用 IIS 时,您会发现与 IOS 证书相关的异常,最常见的异常:
“The credentials supplied to the package were not recognized”
这是由于多种原因造成的,例如您的应用程序池用户权限或安装在用户帐户而不是本地计算机上的证书,因此请尝试禁用 iis 的模拟身份验证并检查它是否真的有用 Apple PushNotification and IIS
我肮脏的快速修复是下载 PushSharp v2.2 的源代码,然后在文件中 ApplePushChannelSettings.cs
我注释掉了关于生产和测试证书的检查:
void CheckProductionCertificateMatching(bool production)
{
if (this.Certificate != null)
{
var issuerName = this.Certificate.IssuerName.Name;
var subjectName = this.Certificate.SubjectName.Name;
if (!issuerName.Contains("Apple"))
throw new ArgumentException("Your Certificate does not appear to be issued by Apple! Please check to ensure you have the correct certificate!");
/*
if (production && !subjectName.Contains("Apple Production IOS Push Services"))
throw new ArgumentException("You have selected the Production server, yet your Certificate does not appear to be the Production certificate! Please check to ensure you have the correct certificate!");
if (!production && !subjectName.Contains("Apple Development IOS Push Services") && !subjectName.Contains("Pass Type ID"))
throw new ArgumentException("You have selected the Development/Sandbox (Not production) server, yet your Certificate does not appear to be the Development/Sandbox certificate! Please check to ensure you have the correct certificate!");
*/
}
else
throw new ArgumentNullException("You must provide a Certificate to connect to APNS with!");
}
并替换了我项目中的 PushSharp.Apple.dll 文件。
希望我的客户升级到 dotnet 4.5,这样我们就可以使用 PushSharp 4 并以正确的方式进行操作。
当我在生产环境中使用具有以下推送通知证书的企业帐户时,我的应用程序收到推送通知:
Apple 生产 iOS 推送服务
然后为了在 App store 中发布我的应用程序,我开始使用 app store 帐户,无论我尝试什么,apple 都会以以下名称创建生产证书:
Apple 推送服务
然后从这个SO,我知道Apple已经更改了证书中的命名。我的问题是,我在服务器端使用 Push Sharp 并出现以下错误:
You have selected the Production server, yet your Certificate does not appear to be the Production certificate! Please check to ensure you have the correct certificate!
中给出的两种解决方案均无效。
我将 Push Sharp 从 2.2 更新到 3.0 beta,遇到很多编译错误,甚至 PushSharp class 本身也不存在,然后尝试了该线程的另一个解决方案。
从 this 下载 PushSharp 并通过删除生产线重新编译它,仍然出现相同的错误。另外那个解决方案不是很清楚,我不确定是否要评论证书检查行还是什么,我试过了但没有运气
如何解决这个问题?
您可以开始使用新的 PushSharp 3.0.1 稳定版,它非常简单而且很棒。
首先,您应该转到并删除所有与 pushsharp 2 相关的 dll:
- PushSharp.Core
- PushSharp.Apple
- PushSharp.Android
等也确保删除:
- Newtonsoft.Json.dll(会产生冲突,我会解释)
然后转到您的项目并打开 nuget 管理器,然后搜索 PushSharp 3 的最新稳定版本并下载它。
现在您应该使用新的 Pushsharp 3 API,它略有不同但更简单:
首先创建一个class,其中包含您想要的所有经纪人:
public class AppPushBrokers
{
public ApnsServiceBroker Apns { get; set; }
public GcmServiceBroker Gcm { get; set; }
public WnsServiceBroker wsb { get; set; }
}
然后在您的业务逻辑/控制器/ViewModel 等方面,您需要编写您的 PushNotification 业务:
public class NewPushHandler
{
#region Constants
public const string ANDROID_SENDER_AUTH_TOKEN = "xxxx";
public const string WINDOWS_PACKAGE_NAME = "yyyy";
public const string WINDOWS_PACKAGE_SECURITY_IDENTIFIER = "zzzz";
public const string WINDOWS_CLIENT_SECRET = "hhhh";
public const string APPLE_APP_NAME = "yourappname";
public const string APPLE_PUSH_CERT_PASS = "applecertpass";
#endregion
#region Private members
bool useProductionCertificate;
string appleCertificateType;
String appleCertName;
String appleCertPath;
byte[] appCertData;
// logger
ILogger logger;
// Config (1- Define Config for each platform)
ApnsConfiguration apnsConfig;
GcmConfiguration gcmConfig;
WnsConfiguration wnsConfig;
#endregion
#region Constructor
public NewPushHandler()
{
// Initialize
useProductionCertificate = true; // you can set it dynamically from config
appleCertificateType = useProductionCertificate == true ? "production.p12" : "development.p12";
appleCertName = APPLE_APP_NAME + "-" + appleCertificateType;
appleCertPath = Path.Combine(Application.StartupPath, "Crt", appleCertName); // for web you should use HttpContext.Current.Server.MapPath(
appCertData = File.ReadAllBytes(appleCertPath);
var appleServerEnv = ApnsConfiguration.ApnsServerEnvironment.Production;
logger = LoggerHandler.CreateInstance();
// 2- Initialize Config
apnsConfig = new ApnsConfiguration(appleServerEnv, appCertData, APPLE_PUSH_CERT_PASS);
gcmConfig = new GcmConfiguration(ANDROID_SENDER_AUTH_TOKEN);
wnsConfig = new WnsConfiguration(WINDOWS_PACKAGE_NAME, WINDOWS_PACKAGE_SECURITY_IDENTIFIER, WINDOWS_CLIENT_SECRET);
}
#endregion
#region Private Methods
#endregion
#region Public Methods
public void SendNotificationToAll(string msg)
{
// 3- Create a broker dictionary
var apps = new Dictionary<string, AppPushBrokers> { {"com.app.yourapp",
new AppPushBrokers {
Apns = new ApnsServiceBroker (apnsConfig),
Gcm = new GcmServiceBroker (gcmConfig),
wsb = new WnsServiceBroker(wnsConfig)
}}};
#region Wire Up Events
// 4- events to fires onNotification sent or failure for each platform
#region Android
apps["com.app.yourapp"].Gcm.OnNotificationFailed += (notification, aggregateEx) =>
{
aggregateEx.Handle(ex =>
{
// See what kind of exception it was to further diagnose
if (ex is GcmConnectionException)
{
// Something failed while connecting (maybe bad cert?)
Console.WriteLine("Notification Failed (Bad APNS Connection)!");
}
else
{
Console.WriteLine("Notification Failed (Unknown Reason)!");
}
// Mark it as handled
return true;
});
};
apps["com.app.yourapp"].Gcm.OnNotificationSucceeded += (notification) =>
{
//log success here or do what ever you want
};
#endregion
#region Apple
apps["com.app.yourapp"].Apns.OnNotificationFailed += (notification, aggregateEx) =>
{
aggregateEx.Handle(ex =>
{
// See what kind of exception it was to further diagnose
if (ex is ApnsNotificationException)
{
var apnsEx = ex as ApnsNotificationException;
// Deal with the failed notification
var n = apnsEx.Notification;
logger.Error("Notification Failed: ID={n.Identifier}, Code={apnsEx.ErrorStatusCode}");
}
else if (ex is ApnsConnectionException)
{
// Something failed while connecting (maybe bad cert?)
logger.Error("Notification Failed (Bad APNS Connection)!");
}
else
{
logger.Error("Notification Failed (Unknown Reason)!");
}
// Mark it as handled
return true;
});
};
apps["com.app.yourapp"].Apns.OnNotificationSucceeded += (notification) =>
{
Console.WriteLine("Notification Sent!");
};
#endregion
#endregion
#region Prepare Notification
// 5- prepare the json msg for android and ios and any platform you want
string notificationMsg = msg;
string jsonMessage = @"{""message"":""" + notificationMsg +
@""",""msgcnt"":1,""sound"":""custom.mp3""}";
string appleJsonFormat = "{\"aps\": {\"alert\":" + '"' + notificationMsg + '"' + ",\"sound\": \"default\"}}";
#endregion
#region Start Send Notifications
// 6- start sending
apps["com.app.yourapp"].Apns.Start();
apps["com.app.yourapp"].Gcm.Start();
//apps["com.app.yourapp"].wsb.Start();
#endregion
#region Queue a notification to send
// 7- Queue messages
apps["com.app.yourapp"].Gcm.QueueNotification(new GcmNotification
{
// You can get this from database in real life scenarios
RegistrationIds = new List<string> {
"ppppp",
"nnnnn"
},
Data = JObject.Parse(jsonMessage),
Notification = JObject.Parse(jsonMessage)
});
apps["com.app.yourapp"].Apns.QueueNotification(new ApnsNotification
{
DeviceToken = "iiiiiii",
Payload = JObject.Parse(appleJsonFormat)
});
#endregion
#region Stop Sending Notifications
//8- Stop the broker, wait for it to finish
// This isn't done after every message, but after you're
// done with the broker
apps["com.app.yourapp"].Apns.Stop();
apps["com.app.yourapp"].Gcm.Stop();
//apps["com.app.yourapp"].wsb.Stop();
#endregion
}
#endregion
}
重要提示:
有时特别是当您使用 IIS 时,您会发现与 IOS 证书相关的异常,最常见的异常:
“The credentials supplied to the package were not recognized”
这是由于多种原因造成的,例如您的应用程序池用户权限或安装在用户帐户而不是本地计算机上的证书,因此请尝试禁用 iis 的模拟身份验证并检查它是否真的有用 Apple PushNotification and IIS
我肮脏的快速修复是下载 PushSharp v2.2 的源代码,然后在文件中 ApplePushChannelSettings.cs
我注释掉了关于生产和测试证书的检查:
void CheckProductionCertificateMatching(bool production)
{
if (this.Certificate != null)
{
var issuerName = this.Certificate.IssuerName.Name;
var subjectName = this.Certificate.SubjectName.Name;
if (!issuerName.Contains("Apple"))
throw new ArgumentException("Your Certificate does not appear to be issued by Apple! Please check to ensure you have the correct certificate!");
/*
if (production && !subjectName.Contains("Apple Production IOS Push Services"))
throw new ArgumentException("You have selected the Production server, yet your Certificate does not appear to be the Production certificate! Please check to ensure you have the correct certificate!");
if (!production && !subjectName.Contains("Apple Development IOS Push Services") && !subjectName.Contains("Pass Type ID"))
throw new ArgumentException("You have selected the Development/Sandbox (Not production) server, yet your Certificate does not appear to be the Development/Sandbox certificate! Please check to ensure you have the correct certificate!");
*/
}
else
throw new ArgumentNullException("You must provide a Certificate to connect to APNS with!");
}
并替换了我项目中的 PushSharp.Apple.dll 文件。
希望我的客户升级到 dotnet 4.5,这样我们就可以使用 PushSharp 4 并以正确的方式进行操作。