我目前正在尝试从 Azure 的通知中心实现直接 Web 推送。 然而,有些东西似乎不起作用,因为推送没有出现,并且在 Azure 内部我收到“外部通知系统错误”
对于 Web 推送,我当前使用 ServiceBusNotification-Format 中的“浏览器”。 这就是我调用 SendDirectNotificationAsync 的方式。
var browserSubscriptionEndpoint = registration.Endpoint;
var browserPushHeaders = new Dictionary<string, string> {
{ "P256DH", registration.P256DH },
{ "Auth", registration.Auth },
};
string body = "{\"title\": \"Notification Title\", \"body\":\"Notification Hub test notification\"}";
return await _client.SendDirectNotificationAsync(new BrowserNotification(body, browserPushHeaders) {
Headers = browserPushHeaders,
}, browserSubscriptionEndpoint);
请求本身成功,并显示 201 OK,我确实收到了响应,并且在返回的结果中显示,NotificationOutcome 已“排队”,但是,通知不会发送到 Azure 本身内部,我将得到我之前说的错误。
请求的一些属性如下:
RequestUri: 'https://testHub.servicebus.windows.net/testHub/messages?api-version=2020-06&direct'
TrackingId: randomTrackingId
ServiceBusNotification-DeviceHandle: https://fcm.googleapis.com/fcm/send/eQA9DO90uUU:test
P256DH: workingP256DHId
Auth: workingAuthId
ServiceBusNotification-Format: browser
traceparent: 00-f6057a955be220cef3f7c7e0fb0d2d4f-661e1efb022a40b0-00
Content-Type: application/json
Content-Length: 79
响应具有以下一些属性:
StatusCode: 201,
ReasonPhrase: 'Created'
Date: Tue, 20 Aug 2024 13:37:11 GMT
Server: Kestrel
Strict-Transport-Security: max-age=2592000
TrackingId: id
x-ms-correlation-request-id: id
X-Powered-By: Azure Notification Hubs
Content-Length: 0
-> 这不是授权问题或注册本身不起作用的问题,因为请求通过了,我尝试使用 Node.js webpush 和 postman 向具有相同授权、vapidkey 等的相同注册端点发出请求,并且我已推送到我的浏览器。因此,就我而言,这些东西应该正确配置。但某些 Azure 特定的东西可能不是。
在我看来,该软件包已过时,因为最新发布日期是 2022 年 2 月 11 日。网站 上引用了 BrowserNotification,但部分实现尚未在实际软件包本身中,它们是最近添加的在 github 中,但没有对该包的官方更新,所以我更改了一些代码以匹配最新的更新,但它似乎仍然不适合我。
在 Azure 中,您可以为通知中心启用诊断日志。这些日志可能会为您提供有关问题所在的更详细信息。
dotnet add package Microsoft.Azure.NotificationHubs --version 4.2.0
根据您的设置检查网络设置后,可能有很多原因。我已经解决了这个问题并重现了这个问题,请检查我的下面的应用程序。
index.js:
const express = require('express');
const webpush = require('web-push');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.json());
const vapidKeys = {
publicKey: 'Your_VAPID_Public_Key',
privateKey: 'Your_VAPID_Private_Key'
};
webpush.setVapidDetails(
'mailto:[email protected]',
vapidKeys.publicKey,
vapidKeys.privateKey
);
app.post('/subscribe', (req, res) => {
const subscription = req.body;
res.status(201).json({});
const payload = JSON.stringify({ title: 'Push Test', body: 'This is a test notification' });
webpush.sendNotification(subscription, payload).catch(error => {
console.error(error.stack);
});
});
const port = 3000;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
public/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Push Test</title>
</head>
<body>
<h1>Web Push Test</h1>
<button id="subscribe">Subscribe to Push Notifications</button>
<script src="main.js"></script>
</body>
</html>
//public/main.js:
const publicVapidKey = 'Your_VAPID_Public_Key';
if ('serviceWorker' in navigator) {
send().catch(err => console.error(err));
}
async function send() {
const register = await navigator.serviceWorker.register('/worker.js', {
scope: '/'
});
const subscription = await register.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(publicVapidKey)
});
await fetch('/subscribe', {
method: 'POST',
body: JSON.stringify(subscription),
headers: {
'Content-Type': 'application/json'
}
});
}
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
return new Uint8Array(rawData.split('').map(char => char.charCodeAt(0)));
}
worker.js:
self.addEventListener('push', event => {
const data = event.data.json();
self.registration.showNotification(data.title, {
body: data.body
});
});
程序.cs:
using Microsoft.Azure.NotificationHubs;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
class Program
{
private static string connectionString = "<Your_Notification_Hub_Connection_String>";
private static string hubName = "<Your_Notification_Hub_Name>";
static async Task Main(string[] args)
{
var client = NotificationHubClient.CreateClientFromConnectionString(connectionString, hubName);
var headers = new Dictionary<string, string>
{
{ "p256dh", "<Client_P256DH_Key>" },
{ "auth", "<Client_Auth_Key>" }
};
var payload = "{\"title\": \"Test Notification\", \"body\": \"This is a test notification from Azure Notification Hub\"}";
var notification = new BrowserNotification(payload, headers);
await client.SendDirectNotificationAsync(notification, "<Client_Endpoint>");
Console.WriteLine("Notification Sent");
}
}
在这里我能够使用
web-push
库成功发送推送通知。
检查 Azure 门户中您可以配置浏览器(Web 推送)的 vapid 密钥的主题,即包含 mailto 的电子邮件地址。例如:“mailto:[email protected]”或者我认为它也可能是一个网址。请参阅文档 如果它只是一些字符串,它将在内部发送通知失败,但不会给你一个适当的反馈。 改变主题后,您必须等待一段时间才能开始工作。对我来说大约需要30分钟。