我只是尝试每件事的Web推送通知,直到最后一步都很好。 我只是使用Service Worker来订阅用户。 代码错误出现在原因阶段。
我刚刚从Git中心获得了这段代码,该链接的完整代码
https://github.com/web-push-libs/web-push-csharp
这是服务人员的注册信息
function subscribeUser() {
const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
.then(function (subscription) {
console.log('User is subscribed.');
updateSubscriptionOnServer(subscription);
isSubscribed = true;
updateBtn();
})
.catch(function (err) {
console.log('Failed to subscribe the user: ', err);
updateBtn();
});
}
function updateSubscriptionOnServer(subscription) {
//var mystring = JSON.stringify(subscription);
$.ajax({
url: "../WebPushHandler.ashx?mystring="+JSON.stringify(subscription),
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (msg) {
console.log(msg);
}
})
if (subscription) {
} else {
}
}
这是请求和响应源代码
public HttpRequestMessage GenerateRequestDetails(PushSubscription subscription, string payload,
Dictionary<string, object> options = null)
{
if (!Uri.IsWellFormedUriString(subscription.endpoint, UriKind.Absolute))
{
throw new ArgumentException(@"You must pass in a subscription with at least a valid endpoint");
}
var request = new HttpRequestMessage(HttpMethod.Post, subscription.endpoint);
if (!string.IsNullOrEmpty(payload) && (string.IsNullOrEmpty(subscription.auth) ||
string.IsNullOrEmpty(subscription.p256dh)))
{
throw new ArgumentException(
@"To send a message with a payload, the subscription must have 'auth' and 'p256dh' keys.");
}
var currentGcmApiKey = _gcmApiKey;
var currentVapidDetails = _vapidDetails;
var timeToLive = DefaultTtl;
var extraHeaders = new Dictionary<string, object>();
if (options != null)
{
var validOptionsKeys = new List<string> { "headers", "gcmAPIKey", "vapidDetails", "TTL" };
foreach (var key in options.Keys)
{
if (!validOptionsKeys.Contains(key))
{
throw new ArgumentException(key + " is an invalid options. The valid options are" +
string.Join(",", validOptionsKeys));
}
}
if (options.ContainsKey("headers"))
{
var headers = options["headers"] as Dictionary<string, object>;
extraHeaders = headers;
//{
// throw new ArgumentException("options.headers must be of type Dictionary<string,object>");
//}
}
if (options.ContainsKey("gcmAPIKey"))
{
var gcmApiKey = options["gcmAPIKey"] as string;
currentGcmApiKey = gcmApiKey;
//{
// throw new ArgumentException("options.gcmAPIKey must be of type string");
//}
}
if (options.ContainsKey("vapidDetails"))
{
var vapidDetails = options["vapidDetails"] as VapidDetails;
currentVapidDetails = vapidDetails;
//{
// throw new ArgumentException("options.vapidDetails must be of type VapidDetails");
//}
}
if (options.ContainsKey("TTL"))
{
var ttl = options["TTL"] as int?;
if (ttl == null)
{
throw new ArgumentException("options.TTL must be of type int");
}
//at this stage ttl cannot be null.
timeToLive = (int)ttl;
}
}
string cryptoKeyHeader = null;
request.Headers.Add("TTL", timeToLive.ToString());
foreach (var header in extraHeaders)
{
request.Headers.Add(header.Key, header.Value.ToString());
}
if (!string.IsNullOrEmpty(payload))
{
if (string.IsNullOrEmpty(subscription.p256dh) || string.IsNullOrEmpty(subscription.auth))
{
throw new ArgumentException(
@"Unable to send a message with payload to this subscription since it doesn't have the required encryption key");
}
var encryptedPayload = Encryptor.Encrypt(subscription.p256dh, subscription.auth, payload);
request.Content = new ByteArrayContent(encryptedPayload.Payload);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
request.Content.Headers.ContentLength = encryptedPayload.Payload.Length;
request.Content.Headers.ContentEncoding.Add("aesgcm");
request.Headers.Add("Encryption", "salt=" + encryptedPayload.Base64EncodeSalt());
cryptoKeyHeader = @"dh=" + encryptedPayload.Base64EncodePublicKey();
}
else
{
request.Content = new ByteArrayContent(new byte[0]);
request.Content.Headers.ContentLength = 0;
}
var isGcm = subscription.endpoint.StartsWith(@"https://android.googleapis.com/gcm/send");
if (isGcm)
{
if (!string.IsNullOrEmpty(currentGcmApiKey))
{
request.Headers.TryAddWithoutValidation("Authorization", "key=" + currentGcmApiKey);
}
}
else if (currentVapidDetails != null)
{
var uri = new Uri(subscription.endpoint);
var audience = uri.Scheme + @"://" + uri.Host;
var vapidHeaders = VapidHelper.GetVapidHeaders(audience, currentVapidDetails.Subject,
currentVapidDetails.PublicKey, currentVapidDetails.PrivateKey, currentVapidDetails.Expiration);
request.Headers.Add(@"Authorization", vapidHeaders["Authorization"]);
if (string.IsNullOrEmpty(cryptoKeyHeader))
{
cryptoKeyHeader = vapidHeaders["Crypto-Key"];
}
else
{
cryptoKeyHeader += @";" + vapidHeaders["Crypto-Key"];
}
}
request.Headers.Add("Crypto-Key", cryptoKeyHeader);
return request;
}
public async Task SendNotificationAsync(PushSubscription subscription, string payload = null,
Dictionary<string, object> options = null)
{
var request = GenerateRequestDetails(subscription, payload, options);
var response = await HttpClient.SendAsync(request);
sendAsyncTask.Wait();
HandleResponse(response, subscription);
}
问题是: 我只是从服务工作者那里正确获取订阅,并生成通过上述方法将所有密钥传递给他们的有效密钥,并生成HttpMessageResponse,这表明SenderId不匹配,并且在var sendAsyncTask = HttpClient处收到请求错误为“ Bad Request 400”。 SendAsync(request);