对于我的环境,我使用Rest API通过通知中心注册/取消注册我的设备。
每当我的用户登录时,我的应用程序向GCM注册,获取注册ID,然后向通知中心注册以接收通知。这没有任何问题。
当我的用户退出时,我的应用想要从通知中心删除该注册,以便用户不再收到任何通知。
咨询本页后如何删除注册
https://msdn.microsoft.com/en-us/library/azure/dn223268.aspx
我写了以下代码:
var client = new XMLHttpRequest();
client.onload = function () {
if (client.readyState == 4) {
if (client.status == 200) {
// we are logged out
console.log("(sendNHDeleteRegistrationRequest) NH delete registration is successful");
chrome.storage.local.set({registered: false});
updateRegisterUI();
} else {
console.log("(sendNHDeleteRegistrationRequest) NH delete registration is not successful");
console.log("(sendNHDeleteRegistrationRequest) HTTP Status: " + client.status + " : " + client.statusText);
console.log("(sendNHDeleteRegistrationRequest) HTTP Response: " + "\n" + client.responseText);
}
}
};
var url = gOriginalUri + "/registrations/" + gRegistrationId + "?api-version=2015-01";
client.open("POST", url, true);
client.setRequestHeader("Content-Type", "application/atom+xml;type=entry;charset=utf-8");
client.setRequestHeader("Authorization", gSasToken);
client.setRequestHeader("x-ms-version", "2015-01");
try {
client.send();
chrome.storage.local.set({registered: false});
updateRegisterUI();
}
catch(err) {
console.log(err.message);
}
但我总是收到这个错误:
(sendNHDeleteRegistrationRequest)NH删除注册不成功
register.js:230(sendNHDeleteRegistrationRequest)HTTP状态:405:方法不允许
register.js:231(sendNHDeleteRegistrationRequest)HTTP响应:
405
指定的HTTP谓词(POST)无效.TrackingId:64cd952b-ffda-42f8-860b-22dd4aa397ea_G3,TimeStamp:7/31/2015 4:00:48 AM
所以我的问题是 1.要在用户退出时停止接收我的应用程序的通知,标准做法是什么?阻止通知在应用程序中触发或从通知中心删除注册? 2.我是否以正确的方式使用此删除注册?为什么我不接收405方法?
谢谢!
答案 0 :(得分:1)
为了删除注册,我使用下面的代码,它是我为ASP.NET .NET Core项目编写的C#代码,但也许有帮助:
const string hubName = "hubname";
const string apiVersion = "?api-version=2015-01";
const string fullSharedAccessKey = @"fullsharedaccesskey";
const string messageChannel = @"/messages";
const string registrationChannel = @"/registrations";
const string installationChannel = @"/installations";
public async Task<int> DeleteRegistration(string registrationId)
{
var accessKey = ToAccessKey(fullSharedAccessKey);
Uri uri = new Uri($"{accessKey.Endpoint}{hubName}{registrationChannel}/{registrationId}/{apiVersion}");
var sasToken = createToken(uri.AbsoluteUri, accessKey.SasKeyName, accessKey.SasKeyValue);
using (HttpClient client = new HttpClient())
{
HttpRequestMessage message = new HttpRequestMessage()
{
RequestUri = uri,
Method = HttpMethod.Delete
};
message.Headers.Add("Authorization", sasToken);
message.Headers.Add("If-Match", "*");
var result = await client.SendAsync(message);
}
return 0;
}
private AzureNotificationsAccessKey ToAccessKey(string connectionString)
{
var key = new AzureNotificationsAccessKey();
// Parse Connection string
char[] separator = { ';' };
string[] parts = connectionString.Split(separator);
for (int i = 0; i < parts.Length; i++)
{
if (parts[i].StartsWith("Endpoint"))
key.Endpoint = "https" + parts[i].Substring(11);
if (parts[i].StartsWith("SharedAccessKeyName"))
key.SasKeyName = parts[i].Substring(20);
if (parts[i].StartsWith("SharedAccessKey"))
key.SasKeyValue = parts[i].Substring(16);
}
return key;
}
/// <summary>
/// Code for generating of SAS token for authorization with Service Bus
///
/// This handy function can be found on this helpful blog post:
/// http://developers.de/blogs/damir_dobric/archive/2013/10/17/how-to-create-shared-access-signature-for-service-bus.aspx
/// </summary>
/// <param name="resourceUri"></param>
/// <param name="keyName"></param>
/// <param name="key"></param>
/// <returns></returns>
private string createToken(string resourceUri, string keyName, string key)
{
TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + 3600); //EXPIRES in 1h
string stringToSign = EncodeUrl(resourceUri) + "\n" + expiry;
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
var sasToken = String.Format(CultureInfo.InvariantCulture,
"SharedAccessSignature sig={1}&se={2}&skn={3}&sr={0}",
EncodeUrl(resourceUri), EncodeUrl(signature), expiry, keyName);
return sasToken;
}
public class AzureNotificationsAccessKey
{
public string Endpoint { get; set; }
public string SasKeyName { get; set; }
public string SasKeyValue { get; set; }
}
答案 1 :(得分:0)
我看到你正在使用POST方法删除注册。你不应该使用DELETE吗?
var url = gOriginalUri + "/registrations/" + gRegistrationId + "?api-version=2015-01";
client.open("POST", url, true);
client.setRequestHeader("Content-Type", "application/atom+xml;type=entry;charset=utf-8");
client.setRequestHeader("Authorization", gSasToken);
client.setRequestHeader("x-ms-version", "2015-01");
尝试:
client.open("DELETE", url, true);
答案 2 :(得分:0)
我更喜欢使用ANH SDK来提供一种方法!
// go to the Acess Policies page to take your ConnectionString and Namespace
var hubClient = NotificationHubClient.CreateClientFromConnectionString("Your Connection String", "Your namespace");
// take the registrations using your FirebaseToken or Tags, for instance
var registrations = await hubClient.GetRegistrationsByChannelAsync(yourFirebaseToken, 100);
// Finally, remove them
foreach (var registration in registrations)
{
await hubClient.DeleteRegistrationAsync(registration);
}