Azure notification hub是微软云提供的消息推送服务。
Xamarin是一个app开发框架,它使用C#来开发winphone,iOS,Android。目前是由微软收购并入自己的开发环境中,可以免费使用。
本文主要介绍Azure notification hub消息推送,Xamarin不作为本文重点。
移动应用程序很多情况下需要进行消息推送。在中国常用的是极光推送,可以进行多平台推送。本文介绍的Azure notification hub也是可以进行多平台消息推送的机制。由于google不在中国提供服务所以在写本文的当前Android还不能接收到google GCM的消息推送。
下图为Azure notification hub消息推送的流程:
1.客户端应用程序向PNS请求handle。PNS是消息推送平台(包括APNS,GCM,WNS,MPNS,ADM,Baidu),对于 GCM,它是一个RegistionID,对于 APNS,它是一个deviceToken。
2.客户端应用程序将此句柄传给应用后端,应用程序后端传给Notification Hub中以供将来使用。Notification Hub 和应用程序后端共同可以看做一个整体,对于GCM, WNS, Apple提供服务。
3.发送推送通知,应用后端通知Notification Hub,Notification Hub根据要推送的平台使用句柄联系相应的PNS,以定向到特定客户端应用程序的实例。PNS 将通知转发到句柄指定的设备。
iOS应用的消息推送配置大家可以参照下面两篇文章配置。
http://jingyan.baidu.com/article/c275f6ba25e94fe33d756719.html
http://my.oschina.net/u/2361492/blog/524021
在配置过程中有出现过一个问题,有些证书不能导出.p12文件。原因是这个证书没有 private key,解决方法可以尝试将这个证书放到login目录下面再查看该证书是否已经有了private key。
iOS消息推送配置中生成的.p12文件在之后Azure notification hub的配置中需要用到。
创建Azure notification hub。
配置apple消息推送服务。
上传apple中生成的.p12文件,Password是.p12导出时设置的密码。
DefaultFullSharedAccessSugbature是访问Notification hub的URL,我们的应用程序后端在推送消息的时候会用到。
现在Azure notification hub的配置完成。
操作Notification Hub推送消息
首先移动设备需要按照自己的平台进行注册。以下代码为Xamarin.Forms的iOS项目部分。
namespace SimpleImageTestApp.iOS
{
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
//向后端API注册
private RegisterClient registerClient = new RegisterClient();
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
//向APNS注册
if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
var pushSettings = UIUserNotificationSettings.GetSettingsForTypes(
UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound,
new NSSet());
UIApplication.SharedApplication.RegisterUserNotificationSettings(pushSettings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
else
{
UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
}
return base.FinishedLaunching(app, options);
}
//向APNS注册得到deviceToken
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
Register(deviceToken);
}
//将该应用程序向APNS注册得到的deviceToken传给服务器后端
private async void Register(NSData deviceToken)
{
try
{
// Modify device token
string _deviceToken = deviceToken.Description;
_deviceToken = _deviceToken.Trim('<', '>').Replace(" ", "");
SimpleImageTestApp.API.Storage.ISaveUser.RegistrationID = _deviceToken;
// Get Mobile Services client
await registerClient.RegisterAsync(_deviceToken, new HashSet<String>());
}
catch (Exception ex)
{
}
}
//接收APNS消息推送
public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
{
NSObject inAppMessage;
bool success = userInfo.TryGetValue(new NSString("aps"), out inAppMessage);
if(success)
{
UILocalNotification notification = new UILocalNotification();
NSDate.FromTimeIntervalSinceNow(1);
notification.AlertAction = "";
notification.AlertBody = inAppMessage.ToString();
UIApplication.SharedApplication.ScheduleLocalNotification(notification);
}
}
public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
{
base.FailedToRegisterForRemoteNotifications(application, error);
}
}
}
Microsoft.Azure.NotificationHubs.NotificationHubClient 是C#代码中操作Notification Hub的类
ConnectionString为配置步骤中的DefaultFullSharedAccessSugbature
应用程序后端连接Notification Hub
var HubClient = NotificationHubClient.CreateClientFromConnectionString("ConnectionString","HubName");
iOS设备向APNS注册后,把得到的deviceToken传到应用程序后端,应用程序后端用deviceToken和tags向Notification Hub注册。
NotificationHubClient.CreateAppleNativeRegistrationAsync(string deviceToken, System.Collections.Generic.IEnumerable<string> tags)
在发送推送消息时可以用tags控制向哪些设备发送,使用tags可以实现向单人、组发送。比如在用户登录之后使用UserID作为tags注册就可以实现给单人发送。由于应用程序可能会受到攻击,因此保护特定标记的注册需要格外小心,tags可以由应用程序后端来给出,这样可以增加标记级安全性。
NotificationHubClient.SendAppleNativeNotificationAsync按照tag发送消息。
System.Threading.Tasks.Task<Microsoft.Azure.NotificationHubs.NotificationOutcome> SendNotificationAsync(string jsonPayload, string tagExpression)
Azure对JavaScript也提供了支持,使用npm install azure-sb安装支持包,调用的函数和C#代码中的函数基本一致