我使用Web push api使用asp.net Web表单中的javascript和c#发送通知以订阅用户。 对于订阅,我使用了notify.permission方法和service worker,当用户允许时,我会将订阅数据保存在数据库中,其中包括公钥,私钥,端点,auth,p256dh。
发送通知,我进行了一项服务,该服务从数据库中获取数据,并使用Service Worker将通知发送给这些用户。 问题是,当我向3000个用户发送通知时,它仅成功发送给700个用户,其余用户则抛出错误 收到意外的响应代码:403 收到意外的响应代码:401
我似乎在身份验证错误中搜索了这些错误,但是由于所有订阅者都使用相同的方法,因此找不到如何避免它的原因,但是为什么大多数失败却很少成功?
https://github.com/web-push-libs/web-push-csharp
我已经在我的asp.net网络表单应用程序中实现了此代码。
createdevice.js文件
Notification.requestPermission().then(function (status) {
debugger;
if (status === 'denied') {`enter code here`
errorHandler('[Notification.requestPermission] Browser denied permissions to notification api.');
} else if (status === 'granted') {
console.log('[Notification.requestPermission] Initializing service worker.');
debugger;
initialiseServiceWorker();
debugger;
subscribe();
}
});
debugger;
function subscription()
navigator.serviceWorker.ready.then(function (reg) {
var subscribeParams = { userVisibleOnly: true };
debugger;
//Setting the public key of our VAPID key pair.
var applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
subscribeParams.applicationServerKey = applicationServerKey;
reg.pushManager.subscribe(subscribeParams)
.then(function (subscription) {
debugger;
isSubscribed = true;
var p256dh = base64Encode(subscription.getKey('p256dh'));
var auth = base64Encode(subscription.getKey('auth'));
console.log(subscription);
var endpoint = subscription.endpoint;
var ajaxResult = $.ajax({
method: "POST",
url: "/index.aspx/saveCredentialsInDb",
data: JSON.stringify({ endpoint: endpoint, p256dh: p256dh, auth: auth }),
contentType: "application/json; charset=utf-8",
dataType: "json",
});
ajaxResult.done(function (result) {
debugger;
if (result.d=="invalid") {
navigator.serviceWorker.ready.then(function (reg) {
debugger;
reg.pushManager.getSubscription().then(function (subscription) {
debugger;
subscription.unsubscribe().then(function (successful) {
debugger;
// You've successfully unsubscribed
window.location = "http://localhost:59290/redirected_page.aspx";
return;
}).catch(function (e) {
})
})
});
}
else if (result.d == "OK") {
console.log("Data Stored " + result.d + " ");
$('#PushEndpoint').val(subscription.endpoint);
$('#PushP256DH').val(p256dh);
$('#PushAuth').val(auth);
}
});
})
.catch(function (e) {
errorHandler('[subscribe] Unable to subscribe to push', e);
});
});
sw.js
self.addEventListener('push',函数(事件)
debugger;
var data = {};
if (event.data) {
data = event.data.json();
}
console.log('Notification Received1:');
console.log(data);
var title = data.Title;
var message = data.Message;
var img = data.Image;`enter code here`
var image1 = "images/TBGWT-Sitcom-Final-1600px.png";
var icon = "images/push-icon.jpg";
var url = "https://google.com/";
const title1 = 'Actions Notification';
const options = {
body: message,
image: image1,
data: url,
requireInteraction: true,
actions: [
{
action: 'close-action',
title: 'Close',
icon: 'images/multiply.png'
}
]
};
event.waitUntil(self.registration.showNotification(title1, options ));
index.aspx文件:
<script src="sw1.js"></script>
<script src="js/CreateDevice.js"></script>
<input id="PushEndpoint" runat="server" />
<input id="PushP256DH" runat="server"/>
<input id="PushAuth" runat="server"/>
<form id="form1" runat="server">
<div>
<asp:Button ID="send_notification" Text="Send Notification" runat="server" OnClick="send_notification_Click"/>
<button id="unsub">Unsub</button>
</div>
</form>
index.aspx.cs
public partial class index : System.Web.UI.Page
{
public string FromServer;
public static string publicKey;
public static string privateKey;
protected void Page_Load(object sender, EventArgs e)
{
var keys = VapidHelper.GenerateVapidKeys();
FromServer = keys.PublicKey;
publicKey = keys.PublicKey;
privateKey = keys.PrivateKey;
StringBuilder strScript = new StringBuilder();
strScript.Append("<script type=\"text/javascript\">");
strScript.Append("var applicationServerPublicKey='");
strScript.Append(FromServer);
strScript.Append("';");
strScript.Append("</script>");
ClientScriptManager script = Page.ClientScript;
if (!script.IsClientScriptBlockRegistered(this.GetType(), "Var"))
{
script.RegisterClientScriptBlock(this.GetType(), "Var", strScript.ToString());
}
}
[WebMethod]
public static string saveCredentialsInDb(string endpoint, string p256dh, string auth)
{
var _publicKey = publicKey;
var _privateKey = privateKey;
var isError = false;
string conStr = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString;
string query = @"INSERT INTO userCredentials (PublicKey, PrivateKey, [Endpoint], Auth, p256dh)
VALUES (@PublicKey, @PrivateKey, @Endpoint, @Auth, @p256dh)";
// create connection and command
SqlConnection cn = new SqlConnection(conStr);
using (SqlCommand cmd = new SqlCommand(query, cn))
{
// define parameters and their values
cmd.Parameters.AddWithValue("@PublicKey", _publicKey);
cmd.Parameters.AddWithValue("@PrivateKey", _privateKey);
cmd.Parameters.AddWithValue("@Endpoint", endpoint);
cmd.Parameters.AddWithValue("@Auth", auth);
cmd.Parameters.AddWithValue("@p256dh", p256dh);
// open connection, execute INSERT, close connection
cn.Open();
//if (isError == false)
//{
cmd.ExecuteNonQuery();
//}
cn.Close();
}
//if (isError == true)
//{
// return "invalid";
//}
//else
//{
return "OK";
//}
}
public class Data
{
[JsonProperty("Title")]
public string Title { get; set; }
[JsonProperty("Message")]
public string Message { get; set; }
[JsonProperty("Image")]
public string Image { get; set; }
}
public class TimeToLive
{
public int Num { get; set; }
}
protected void send_notification_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
string message = "";
string title = "";
byte[] image = new byte[] { };
string publicKey1 = "";
string privateKey1 = "";
string endpoint = "";
string auth = "";
string p256dh = "";
string base64image = "";
List<string> listData = new List<string>();
string conStr = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString;
string query = @"SELECT * from userCredentials, [Payload]";
// create connection and command
SqlConnection cn = new SqlConnection(conStr);
using (SqlCommand cmd = new SqlCommand(query, cn))
{
// define parameters and their values
// open connection, execute INSERT, close connection
cn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dt);
cn.Close();
}
Data body = new Data();
foreach (DataRow row in dt.Rows)
{
//message = row["Message"].ToString();
//title = row["Title"].ToString();
publicKey1 = row["PublicKey"].ToString();
privateKey1 = row["PrivateKey"].ToString();
endpoint = row["Endpoint"].ToString();
auth = row["Auth"].ToString();
p256dh = row["p256dh"].ToString();
message = row["Message"].ToString();
title = row["Title"].ToString();
//string strfn = Convert.ToString(DateTime.Now.ToFileTime());
//FileStream fs = new FileStream(strfn,
// FileMode.CreateNew, FileAccess.Write);
//fs.Write(Bimage, 0, Bimage.Length);
//fs.Flush();
//fs.Close();
// FromFile(strfn);
//image = "data:images/png;base64,"+ base64image;
}
//listData.Add(title);
//listData.Add(message);
body.Title = title;
body.Message = message;
//body.Image = base64image.ToString();
var payload = JsonConvert.SerializeObject(body);
var pushSubscription = new PushSubscription(endpoint, p256dh, auth);
//var vapidDetails = new VapidDetails("mailto:example@example.com", publicKey1, privateKey1);
var options = new Dictionary<string, object>();
options["vapidDetails"] = new VapidDetails("mailto:example@example.com", publicKey1, privateKey1);
//TimeToLive ttl = new TimeToLive();
//ttl.Num = 3600;
//options["TTL"] = 3600;
var webPushClient = new WebPushClient();
try
{
webPushClient.SendNotificationAsync(pushSubscription, payload, options);
}
catch (WebPushException ex)
{
throw ex;
}
}
}
当发送到3000个订阅者时,它发送到700个订阅者,其余的发送失败,并在index.aspx.cs文件中引发错误:
webPushClient.SendNotificationAsync(pushSubscription,有效负载,选项);
收到意外的响应代码:401 收到意外的响应代码:403
其余的代码用于了解客户端发生的情况以及我如何实现它。