Центр уведомлений Azure и промежуточные уведомления WP8
Это довольно длинный кусок кода, но я ни к чему не привыкла и не вижу никаких проблем, хотя я новичок в использовании концентраторов уведомлений. Я пытаюсь зарегистрироваться для целевых уведомлений (вошедших в систему пользователей) с помощью центра уведомлений в Azure. После регистрации отправляется тестовое уведомление.
У меня проблема в том, что иногда на устройство отправляется уведомление, а иногда нет. В основном это не так, но иногда, когда я перебираю код на сервере, я получаю уведомление на эмуляторе. Однажды, когда я развернул приложение на своем телефоне, на эмуляторе пришло уведомление! Я не могу обнаружить образец.
Мой класс Controller выглядит следующим образом;
private NotificationHelper hub;
public RegisterController()
{
hub = NotificationHelper.Instance;
}
public async Task<RegistrationDescription> Post([FromBody]JObject registrationCall)
{
var obj = await hub.Post(registrationCall);
return obj;
}
И вспомогательный класс (который используется в другом месте, поэтому не находится непосредственно в контроллере) выглядит следующим образом;
public static NotificationHelper Instance = new NotificationHelper();
public NotificationHubClient Hub { get; set; }
// Create the client in the constructor.
public NotificationHelper()
{
var cn = "<my-cn>";
Hub = NotificationHubClient.CreateClientFromConnectionString(cn, "<my-hub>");
}
public async Task<RegistrationDescription> Post([FromBody] JObject registrationCall)
{
// Get the registration info that we need from the request.
var platform = registrationCall["platform"].ToString();
var installationId = registrationCall["instId"].ToString();
var channelUri = registrationCall["channelUri"] != null
? registrationCall["channelUri"].ToString()
: null;
var deviceToken = registrationCall["deviceToken"] != null
? registrationCall["deviceToken"].ToString()
: null;
var userName = HttpContext.Current.User.Identity.Name;
// Get registrations for the current installation ID.
var regsForInstId = await Hub.GetRegistrationsByTagAsync(installationId, 100);
var updated = false;
var firstRegistration = true;
RegistrationDescription registration = null;
// Check for existing registrations.
foreach (var registrationDescription in regsForInstId)
{
if (firstRegistration)
{
// Update the tags.
registrationDescription.Tags = new HashSet<string>() {installationId, userName};
// We need to handle each platform separately.
switch (platform)
{
case "windows":
var winReg = registrationDescription as MpnsRegistrationDescription;
winReg.ChannelUri = new Uri(channelUri);
registration = await Hub.UpdateRegistrationAsync(winReg);
break;
case "ios":
var iosReg = registrationDescription as AppleRegistrationDescription;
iosReg.DeviceToken = deviceToken;
registration = await Hub.UpdateRegistrationAsync(iosReg);
break;
}
updated = true;
firstRegistration = false;
}
else
{
// We shouldn't have any extra registrations; delete if we do.
await Hub.DeleteRegistrationAsync(registrationDescription);
}
}
// Create a new registration.
if (!updated)
{
switch (platform)
{
case "windows":
registration = await Hub.CreateMpnsNativeRegistrationAsync(channelUri,
new string[] {installationId, userName});
break;
case "ios":
registration = await Hub.CreateAppleNativeRegistrationAsync(deviceToken,
new string[] {installationId, userName});
break;
}
}
// Send out a test notification.
await SendNotification(string.Format("Test notification for {0}", userName), userName);
return registration;
И наконец, мой метод SendNotification здесь;
internal async Task SendNotification(string notificationText, string tag)
{
try
{
var toast = PrepareToastPayload("<my-hub>", notificationText);
// Send a notification to the logged-in user on both platforms.
await NotificationHelper.Instance.Hub.SendMpnsNativeNotificationAsync(toast, tag);
//await hubClient.SendAppleNativeNotificationAsync(alert, tag);
}
catch (ArgumentException ex)
{
// This is expected when an APNS registration doesn't exist.
Console.WriteLine(ex.Message);
}
}
Я подозреваю, что проблема в коде моего телефона клиента, который находится здесь, и SubscribeToService вызывается сразу после входа в WebAPI;
public void SubscribeToService()
{
_channel = HttpNotificationChannel.Find("mychannel");
if (_channel == null)
{
_channel = new HttpNotificationChannel("mychannel");
_channel.Open();
_channel.BindToShellToast();
}
_channel.ChannelUriUpdated += async (o, args) =>
{
var hub = new NotificationHub("<my-hub>", "<my-cn>");
await hub.RegisterNativeAsync(args.ChannelUri.ToString());
await RegisterForMessageNotificationsAsync();
};
}
public async Task RegisterForMessageNotificationsAsync()
{
using (var client = GetNewHttpClient(true))
{
// Get the info that we need to request registration.
var installationId = LocalStorageManager.GetInstallationId(); // a new Guid
var registration = new Dictionary<string, string>()
{
{"platform", "windows"},
{"instId", installationId},
{"channelUri", _channel.ChannelUri.ToString()}
};
var request = new HttpRequestMessage(HttpMethod.Post, new Uri(ApiUrl + "api/Register/RegisterForNotifications"));
request.Content = new StringContent(JsonConvert.SerializeObject(registration), Encoding.UTF8, "application/json");
string message;
try
{
HttpResponseMessage response = await client.SendAsync(request);
message = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
message = ex.Message;
}
_registrationId = message;
}
}
Любая помощь будет очень ценной, так как я застрял на этом уже несколько дней! Я знаю, что здесь много кода, который нужно вставить, но все это актуально. Спасибо,
РЕДАКТИРОВАТЬ: метод SubscribeToService() вызывается, когда пользователь входит в систему и аутентифицируется с помощью WebAPI. Метод здесь;
public async Task<User> SendSubmitLogonAsync(LogonObject lo)
{
_logonObject = lo;
using (var client = GetNewHttpClient(false))
{
var logonString = String.Format("grant_type=password&username={0}&password={1}", lo.username, lo.password);
var sc = new StringContent(logonString, Encoding.UTF8);
var response = await client.PostAsync("Token", sc);
if (response.IsSuccessStatusCode)
{
_logonResponse = await response.Content.ReadAsAsync<TokenResponseModel>();
var userInfo = await GetUserInfoAsync();
if (_channel == null)
SubscribeToService();
else
await RegisterForMessageNotificationsAsync();
return userInfo;
}
// ...
}
}
2 ответа
Я решил проблему. Есть тонны довольно плохо организованных инструкций для лазурных узлов уведомлений, и только у одного из них есть это примечание к основанию;
НОТА:
Вы не будете получать уведомления, когда вы еще в приложении. Чтобы получать всплывающее уведомление, когда приложение активно, вы должны обработать событие ShellToastNotificationReceived.
Вот почему я испытывал прерывистые результаты, так как предполагал, что вы все равно получите уведомление, если будете в приложении. И эта маленькая записка довольно хорошо спрятана.
Использовали ли вы правильный тег / выражение тега при регистрации / отправке сообщения. Кроме того, где вы храните идентификатор обратно из центра уведомлений. Его следует использовать при обновлении канала uri (срок его действия истекает).
Я бы предложил начать с нуля.
Ссылка: http://msdn.microsoft.com/en-us/library/dn530749.aspx