Asp.net PushSharp 4.0.10.0:基于HTTP/2的苹果推送通知服务(APNs)

Asp.net PushSharp 4.0.10.0:基于HTTP/2的苹果推送通知服务(APNs),asp.net,push-notification,apple-push-notifications,Asp.net,Push Notification,Apple Push Notifications,我们使用PushSharp 4.0.10发送iOS推送通知: 最近,我们收到了来自Apple Developer的以下电子邮件: “如果您仍然使用传统的二进制协议发送推送通知,那么是时候更新到基于HTTP/2的Apple推送通知服务(APNs)提供程序API了。您将能够利用强大的功能,例如使用JSON Web令牌进行身份验证、改进的错误消息传递和每通知反馈。 为了给您更多的准备时间,升级到APNs提供商API的截止日期已延长至2021年3月31日。我们建议尽快升级,因为APNs在此日期后将不再

我们使用PushSharp 4.0.10发送iOS推送通知:

最近,我们收到了来自Apple Developer的以下电子邮件:

“如果您仍然使用传统的二进制协议发送推送通知,那么是时候更新到基于HTTP/2的Apple推送通知服务(APNs)提供程序API了。您将能够利用强大的功能,例如使用JSON Web令牌进行身份验证、改进的错误消息传递和每通知反馈。 为了给您更多的准备时间,升级到APNs提供商API的截止日期已延长至2021年3月31日。我们建议尽快升级,因为APNs在此日期后将不再支持传统二进制协议。”


我的问题是:2021年3月31日之后,PushSharp 4.0.10是否仍能正常工作?

对此进行了讨论,但讨论已经结束。但是关于这个主题,仍然有一些建议,您可能想尝试一下

从2020年11月起,苹果推送通知服务(APNs)将不再支持传统二进制协议

** 编辑日期:2021年3月25日

截止日期快到了,@Ashita Shah询问了一些代码片段,所以我希望下面的内容可以节省您的时间

将以下类dotansservice添加到项目中。您可以根据需要定制此结构。此外,在实现我自己的推送通知服务时,我没有关注最好的编码C#标准。您可以实现LINQ、异步任务等。我测试了这个dotans库,它工作得非常好。对于Android,您仍然可以使用PushSharp

在实现dotansservicehelper类之前,请从您的Apple开发者帐户获取以下信息。ApnsJwtOptions值应为:

BundleId-您的应用程序的bundle ID不应包括特定主题(即com.myapp,但不包括com.myapp.voip)

CertFilePath-从开发人员中心下载的.p8证书的路径

KeyId-从开发者帐户获得的10个字符的密钥ID

团队ID-用于开发公司应用程序的10个字符的团队ID。从开发人员帐户获取此值

public class dotAPNSService : IDisposable
{
    public event EventHandler OnTokenExpiredHandler;
    private ApnsJwtOptions options = null;
    
    public dotAPNSService()
    {
        options = new ApnsJwtOptions()
        {
            BundleId = "com.xx.xxxx",
            CertFilePath = "../../certificate.p8",
            KeyId = "The_Key_Id",
            TeamId = "The_Team_Id"
        };
    }

    public void SendNotifications(String[] deviceTokens, String title, String body)
    {
        if (deviceTokens == null || deviceTokens.Length <= 0)
        {
            return;
        }

        if (String.IsNullOrEmpty(title))
        {
            return;
        }

        if (String.IsNullOrEmpty(body))
        {
            return;
        }

        // once you've gathered all the information needed and created an options instance, it's time to call
        var apns = ApnsClient.CreateUsingJwt(new HttpClient(), options);

        // start the process     
        foreach (String deviceToken in deviceTokens)
        {
            var push = new ApplePush(ApplePushType.Alert)
                .AddAlert(title, body)
                .AddToken(deviceToken);

            Send(apns, push, deviceToken);
        }
    }

    public void SendSilentNotifications(String[] deviceTokens)
    {
        try
        {
            if (deviceTokens == null || deviceTokens.Length <= 0)
            {
                return;
            }

            // once you've gathered all the information needed and created an options instance, it's time to call
            var apns = ApnsClient.CreateUsingJwt(new HttpClient(), options);

            // start the process               
            foreach (String deviceToken in deviceTokens)
            {
                var push = new ApplePush(ApplePushType.Background)
                    .AddContentAvailable()
                    .AddToken(deviceToken);

                Send(apns, push, deviceToken);
            }
        }
        finally
        {

        }
    }

    private void Send(ApnsClient apns, ApplePush push, String deviceToken)
    {
        try 
        {
            var response = apns.SendAsync(push);
            if (response.Result.Reason == ApnsResponseReason.Success)
            {
                // the notification has been sent!
            }
            else 
            {
                Boolean removeToken = false;
                switch (response.Result.Reason)
                {
                    case ApnsResponseReason.BadDeviceToken:
                        removeToken = true;
                        break;
                    case ApnsResponseReason.TooManyRequests:
                        break;
                }

                // remove the token from database?
                if (removeToken)
                    OnTokenExpired(new ExpiredTokenEventArgs(deviceToken));
            }
        }
        catch (TaskCanceledException)
        {
            // ERROR - HTTP request timed out, you can use the deviceToken to log the error
        }
        catch (HttpRequestException ex)
        {
            // ERROR - HTTP request failed, you can use the deviceToken to log the error
        }
    }

    protected virtual void OnTokenExpired(ExpiredTokenEventArgs args)
    {
        try
        {
            EventHandler handler = OnTokenExpiredHandler;
            if (handler != null)
            {                    
                ISynchronizeInvoke target = handler.Target as ISynchronizeInvoke;
                if (target != null && target.InvokeRequired)
                    target.Invoke(handler, new object[] { this, args });
                else
                    handler(this, args);
            }
        }
        catch (Exception ex)
        {
           
        }
    }
}
要在项目中使用dotansservice帮助程序,只需从数据库中提取令牌,然后将其传递给它即可。例如,要发送静默通知,请执行以下操作:

public void SendScheduledSilentNotifications()
{
    try
    {
        IList<User> users = _accountService.GetUsers(true);
        if (users != null && users.Count > 0)
        {
            List<String> deviceTokens = new List<String>();
            foreach (User user in users)
            {
                if (!String.IsNullOrEmpty(user.DeviceToken))
                    deviceTokens.Add(user.DeviceToken);
            }
    
            if (deviceTokens.Count > 0)
            {
                using (dotAPNSService service = new dotAPNSService())
                {
                    service.OnTokenExpiredHandler += new EventHandler(OnTokenExpired);
                    service.SendSilentNotifications(deviceTokens.ToArray());
                }
            }
        }
    }
    finally
    {
    
    }
}
您可以从以下位置下载源代码:


API现在一次发送数千个静默通知,没有延迟、崩溃等。希望此代码片段能够帮助您节省时间

我删除了PushSharp并实现了DoTans。高度建议,易于使用:谢谢你的提示。我猜dotAPNS只适用于Apple/iOS,你用什么发送推送到Android?是的,它只适用于Apple,但这项工作的目的是实现http/2到Apple推送通知,这样你仍然可以在Android上使用PushSharp。只需实现dotAPNS,在发送通知时,请检查通知是否需要发送给iOS用户:)简单的解决方法。请共享实现dotAPNS的代码片段。@AshitaShah我希望这能有所帮助。
public void SendScheduledSilentNotifications()
{
    try
    {
        IList<User> users = _accountService.GetUsers(true);
        if (users != null && users.Count > 0)
        {
            List<String> deviceTokens = new List<String>();
            foreach (User user in users)
            {
                if (!String.IsNullOrEmpty(user.DeviceToken))
                    deviceTokens.Add(user.DeviceToken);
            }
    
            if (deviceTokens.Count > 0)
            {
                using (dotAPNSService service = new dotAPNSService())
                {
                    service.OnTokenExpiredHandler += new EventHandler(OnTokenExpired);
                    service.SendSilentNotifications(deviceTokens.ToArray());
                }
            }
        }
    }
    finally
    {
    
    }
}
private void OnTokenExpired(object sender, EventArgs e)
{
    if (e == null)
        return;

    if (e.GetType() == typeof(ExpiredTokenEventArgs))
    {
        var args = (ExpiredTokenEventArgs)e;
        User user = _accountService.GetUserByDeviceToken(args.Token);
        if (user != null)
        {
            user.DeviceToken = String.Empty;
            Boolean success = !(_accountService.SaveUser(user) == null);
            if (success)
                // INFO - expired device token has been removed from database
            else
                // INFO - something went wrong
        }   
    }
}