PushSharp - ios - StopAllServices() 挂起且没有错误

Posted

技术标签:

【中文标题】PushSharp - ios - StopAllServices() 挂起且没有错误【英文标题】:PushSharp - ios - StopAllServices() hangs with no errors 【发布时间】:2014-07-02 12:27:07 【问题描述】:

我正在尝试通过 PushSharp 向 ios 设备发送推送通知。对于安卓,它可以工作。对于 IOS,对StopAllServices() 的调用将永远挂起,而不会调用任何异常处理程序。

问题可能是给了我一个 .pem 证书文件,而 pushsharp 需要一个 .p12 文件吗?

代码如下:

var br = new PushBroker();
br.OnNotificationSent += br_OnNotificationSent;
br.OnNotificationFailed += br_OnNotificationFailed;
br.OnChannelException += br_OnChannelException;
br.OnServiceException += br_OnServiceException;
br.OnDeviceSubscriptionChanged += br_OnDeviceSubscriptionChanged;
br.OnDeviceSubscriptionExpired += br_OnDeviceSubscriptionExpired;
br.OnChannelCreated += br_OnChannelCreated;
br.OnChannelDestroyed += br_OnChannelDestroyed;

var appleCert = Resource1.ck; // this is a pem file, not a p12 file!!! could this be the problem?
var sandbox = true;
br.RegisterAppleService(new ApplePushChannelSettings(!sandbox, appleCert, "223684"));
// password given to me by ios developer

var deviceIds = new string[]  "09eddcb8b89494adf802a0caf97d5daaa789a53f52d8c544dbdcf39f2c0b619a" ;

foreach (var did in deviceIds)

    br.QueueNotification(
         new AppleNotification()
               .ForDeviceToken(did)//the recipient device id
               .WithAlert("test: " + DateTime.Now.ToString())//the message
               .WithBadge(1)
               .WithSound("sound.caf"));

br.StopAllServices(waitForQueuesToFinish: true); // hangs forever, no callbacks are called

截至昨天,我正在使用通过 Git 获取的 PushSharp,并由我自己使用 Visual Studio 2013 编译。

如果代码位于控制台应用程序和 asp.net 应用程序中,则会发生挂起。

我正在使用沙盒,因为有人告诉我这样做。如果我使用生产服务器,我会收到一个异常,告诉我证书是用于沙盒的。

感谢您提供有关冻结原因的任何提示。

【问题讨论】:

您能等几秒钟br_OnNotificationFailed 或任何其他事件吗?它应该包含一些错误描述。 抱歉,您所说的“等待 br_onnotificationfailed 几秒钟”是什么意思?这是一个回调,而不是等待。它没有被调用。 PushSharp 回调通常在几秒钟后被调用。我也不确定当你用waitForQueuesToFinish 阻塞你的线程时如何接收回调——这不是死锁吗?通过等待,我正在考虑让程序正常运行并查看您是否收到任何回调。尽管如此,我还是会调查证书问题——有一天这让我很头疼。 【参考方案1】:

我们花了一整天的时间来猜测问题所在! 最终是在错误的 Newtonsoft.Json 版本中 我们解决方案中的一些项目依赖于这个库的旧版本,因此我们很不幸在 Web 项目的 /bin 文件夹中得到了错误的版本。

【讨论】:

谢谢。它解决了我的问题。【参考方案2】:

您可以等待几秒钟 br_OnNotificationFailed 或任何其他可能的事件。它应该包含一些错误描述。

不过,我发现 PushSharp 对证书的使用有严格的要求。 PEM 应该没问题,但这还不够,即使您从文件中导入它 - 您应该在 Windows 证书存储中拥有所有必要的证书(pem 本身及其依赖项):

    将您的 PEM 导入 Local Machine\Root 存储并将其私钥的读取访问权限授予正在运行的应用程序的用户

    从Apple site 证书Apple 全球开发者关系证书颁发机构Apple 根 CA 导入 本地机器\受信任的根证书颁发机构

    Entrust Secure CA 证书(用于iOS Developer Library 中所述的 SSL)导入 本地机器\受信任的根证书颁发机构

【讨论】:

“将您的 PEM 导入本地计算机\根存储”:我找不到执行此操作的指南。 Pageant.exe 无法导入它。右键单击菜单不显示任何内容。我在 Windows 8 中。 @seguso, here 你有一个小教程。但是您可能需要将此 pem 转换为 pfx,如 here 所述。 谢谢。我无法将 pem 转换为 p12,因为我需要两个 pem,而 ios 开发人员不会将两者都给我。我向他要了一个 p12,他做了一个并给了我,现在我得到了一个不同的错误。这次抛出异常: CryptographicExcepion,由 new ApplePushChannelSettings(!sandbox, appleCert, "223684") 抛出。我想我需要为此提出一个新问题...... p12 是否无效或创建不正确?【参考方案3】:

最后是证书问题。 PushSharp 不接受给我的 .pem。仅当我获得使用本指南创建的 .p12 时

https://code.google.com/p/apns-sharp/wiki/HowToCreatePKCS12Certificate

,问题解决了。

但是,PushSharp 应该引发异常而不是挂起。

【讨论】:

【参考方案4】:

ASP.NET 应用程序不是使用 PushSharp 的理想场所。如果可能的话,您最好使用 Windows 服务或其他一些基础设施。原因是在 ASP.NET 应用程序中,应用程序池 (AppPool) 可以在您身上重新启动,并且通常不受您的直接控制,这意味着 PushSharp 可能正在发送的所有排队通知可能会丢失,如果PushSharp 没有被优雅地清理。

如果您必须在 ASP.NET 应用程序中运行 PushSharp,最好的方法是在您的 Global.asax 文件中创建一个单例 PushBroker 实例。您应该在 Web 应用程序的整个生命周期内保留这个单例实例,包括在应用程序结束时调用 pushBroker.StopAllServices()(global.asax 中的 Application_End)。

您可以通过持久保存您希望以其他方式发送的通知,并且仅在触发 OnNotificationSent 事件后将其从该持久存储中删除,从而帮助减轻由于无法预见的应用程序池终止或重新启动而导致的消息丢失。这仍然不是完美的(您可能会冒多次发送通知的风险),但对于大多数人来说可能已经足够了。

您不应该在每次发送通知时创建和销毁 PushBroker 实例,因为这会使用不必要的资源,如果您使用的是 Apple APNS,它们会要求您尽可能长时间地保持与其服务器的连接打开发送通知。您还应该在 Global.asax 的 Application_Ended 事件中调用 pushBroker.StopAllServices()。请记住,PushSharp 有效。

参考:https://github.com/Redth/PushSharp/issues/240

【讨论】:

以上是关于PushSharp - ios - StopAllServices() 挂起且没有错误的主要内容,如果未能解决你的问题,请参考以下文章

PushSharp 错误消息发送 IOS 推送通知

使用 PushSharp 2.2.1.0 iOS 发送通知时出错

pushsharp 2 在向苹果 ios 发送通知时触发异常

iOS 设备令牌的 Pushsharp 4.0.10.0 ApnsConfiguration 连接错误

在 c# 中使用 Pushsharp 的 IOS 推送通知

如何使用库 PushSharp 向 iOS 发送推送通知?