-1

我是 azure 的新手,我已经将我的应用程序配置为接收原始通知,并且我能够从 azure 网站的调试页面接收它们,我的问题是,我如何从我的后端发送它们?我能够发送所有类型的通知,但不知道如何发送那种类型...一个非常简单的通知,比如天蓝色的通知(Windows 不是 Windows 手机),只是一个没有格式化的字符串

4

3 回答 3

6

假设您使用的是 WNS(而不是 MPNS),您只需从 hub.wns 对象调用 SendRaw。语法是:

sendRaw(tags, payload, optionsOrCallbackopt, callback)

请参阅位于http://dl.windowsazure.com/nodedocs/WnsService.html的推送通知中心中的 WNS 服务的 NodeJS 文档。

对于 .NET 后端,您可以使用https://msdn.microsoft.com/en-us/library/azure/dn369343.aspx中记录的NotificationHubClient.SendNotificationAsync。您输入的通知类将是 WindowsNotification,如https://msdn.microsoft.com/en-us/library/azure/microsoft.servicebus.notifications.windowsnotification.aspx中所述。

由于您想发送原始通知,因此您必须自己创建有效负载。有关如何创建原始有效负载的文档位于https://msdn.microsoft.com/en-us/library/windows/apps/jj676791.aspx,更具体地说:

  • HTTP Content-Type 标头必须设置为“application/octet-stream”。
  • HTTP X-WNS-Type 标头必须设置为“wns/raw”。
  • 通知正文可以包含任何小于 5 KB 的字符串负载。
于 2015-07-10T18:31:53.380 回答
0

此后,一位 Microsoft 工程师为我提供了以下示例程序,它也能够发送原始通知,我认为在这里分享它是合适的:

using Newtonsoft.Json.Linq;
using System;
using System.Globalization;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace ConsoleApp
{
    class Program
    {
        static string NH_NAMESPACE = "{Please input}";
        static string HUB_NAME = "{Please input}";
        static string KEY_NAME = "DefaultFullSharedAccessSignature";
        static string KEY_VALUE = "{Please input}";

        static void Main(string[] args)
        {
            JObject jobject = new JObject();
            jobject.Add("text1", "my app");
            jobject.Add("text2", "my value");

            SendNotificaitonAsync(jobject.ToString()).Wait();

            Console.ReadLine();
        }

        private static async Task SendNotificaitonAsync(string content)
        {
            string resourceUri = $"https://{NH_NAMESPACE}.servicebus.windows.net/{HUB_NAME}/messages/";
            using (var request = CreateHttpRequest(HttpMethod.Post, resourceUri))
            {
                request.Content = new StringContent(content, Encoding.UTF8, "application/octet-stream");
                request.Content.Headers.ContentType.CharSet = string.Empty;
                var httpClient = new HttpClient();
                var response = await httpClient.SendAsync(request);
                Console.WriteLine(response.StatusCode);
            }
        }

        private static HttpRequestMessage CreateHttpRequest(HttpMethod method, String resourceUri)
        {
            var request = new HttpRequestMessage(method, $"{resourceUri}?api-version=2017-04");
            request.Headers.Add("Authorization", createToken(resourceUri, KEY_NAME, KEY_VALUE));
            request.Headers.Add("X-WNS-Type", "wns/raw");
            request.Headers.Add("ServiceBusNotification-Format", "windows");

            return request;
        }

        private static string createToken(string resourceUri, string keyName, string key)
        {
            TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
            var week = 60 * 60 * 24 * 7;
            var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + week);
            string stringToSign = HttpUtility.UrlEncode(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 sr={0}&sig={1}&se={2}&skn={3}", HttpUtility.UrlEncode(resourceUri), HttpUtility.UrlEncode(signature), expiry, keyName);
            return sasToken;
        }
    }
}
于 2018-10-09T00:15:19.573 回答
0

以下是一些将执行此任务的工作代码(符合 .Net Standard 2.0):

  public static async Task SendRawNotification(string notificationString)
  {
    var sasToken = CreateSASToken($"http://{NotificationNamespace}.servicebus.windows.net/{NotificationHub}", "DefaultFullSharedAccessSignature", $"{SharedAccessKey}");

    var description = new NotificationDescription
    {
      NotificationType = type,
      Notification = JsonConvert.SerializeObject(notification)
    };
    var serialized = JsonConvert.SerializeObject(description);
    byte[] contentInBytes = Encoding.UTF8.GetBytes(serialized);

    HttpWebRequest request = WebRequest.Create($"https://{NotificationNamespace}.servicebus.windows.net/{NotificationHub}/messages/?api-version=2015-01") as HttpWebRequest;
    request.Method = "POST";
    request.ContentType = "application/octet-stream";
    request.Headers.Add("Authorization", sasToken);
    request.Headers.Add("X-WNS-Type", "wns/raw");
    request.Headers.Add("ServiceBusNotification-Format", "windows");


    using (Stream requestStream = request.GetRequestStream())
      requestStream.Write(contentInBytes, 0, contentInBytes.Length);

    using (HttpWebResponse webResponse = await request.GetResponseAsync() as HttpWebResponse)
    {
      if (webResponse.StatusCode != HttpStatusCode.Created)
      {
        throw new InvalidOperationException($"Failed to create notification: {serialized}");
      }
    }
  }

private static string CreateSASToken(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 = HttpUtility.UrlEncode(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 sr={0}&sig={1}&se={2}&skn={3}",
      HttpUtility.UrlEncode(resourceUri), HttpUtility.UrlEncode(signature), expiry, keyName);

  return sasToken;
}

此问题的先前答案包含无效链接,并且没有提供有关如何实现此功能的有用信息。

不幸的是,在撰写此回复时,Azure Notification Hub SDK 在使用 NuGet 包时发送原始通知方面出现问题:Microsoft.Azure.NotificationHubs (2.0.0)

此功能在 Microsoft.Azure.NotificationHubs (1.0.9) 中可用并且仍然有效,但是,这仅在面向 4.6.1 的 .Net Framework 项目中可用。

如果您希望在.NetCore 或.NetStandard 2.0 项目中发送原始通知,那么您将在发送时收到类似于“您必须将内容类型设置为 'application/octet-stream'”的异常信息。这是因为,在 SDK 本身中,他们使用 StringContent 对象构造 HttpRequest,该对象将“charset-utf8”附加到 ContentType 标头。

在发布 NuGet 包的更新之前(Microsoft 已意识到此问题并且目前正在努力提供更新),然后您必须自己创建 HttpRequest。

不幸的是,微软关于如何实现这一点的文档再次严重缺乏细节。

有几个步骤可以完成此操作,如下所示:

  1. 创建您的资源 URI 字符串

您尝试使用的资源的 Uri。为了向 Azure 通知中心发送请求,其格式应如下所示: https://{NotificationHubNamespace}.servicebus.windows.net/{NotificationHubName}

因此,如果您的通知命名空间是“notification-ns”并且您的通知中心称为“notification-hub”,那么 URI 应该是: https://notification-ns.servicebus.windows.net/notification-hub

  1. 从 Azure 门户保存 DefaultSharedAccessSignature

您需要从 Azure 门户复制您的 DefaultFullSharedAccessSignature。您的签名应如下所示: Endpoint=sb://xxxx.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=xxxxxxxxx=

复制/保存“SharedAccessKey =”后面的部分,因为它用于生成访问令牌。

  1. 生成您的 SharedAccessSignature 令牌(SAS 密钥)

调用 CreateSASToken 函数,设置参数如下:resourceUri:"https://{NotificationHubNamespace}.servicebus.windows.net/{NotificationHubName}" keyName: "DefaultFullSharedAccessSignature" key: the saved part following "SharedAccessKey=" in the DefaultFullSharedAccessSignature

这将生成一个格式正确的SharedAccessSignature (SAS Key)

现在,您可以使用System.Net.Http library来创建HttpWebRequest发送原始通知。

于 2018-10-05T02:08:00.357 回答