public async Task <string> ServerPush(string message) { var response = new StringBuilder(); var pushMessage = new WP.PushMessage(message) { Topic = "Debug", Urgency = WP.PushMessageUrgency.Normal }; await _subscriptionStore.ForEachSubscriptionAsync(_applicationUser.Id, (subscription) => { _notificationService.SendNotificationAsync(subscription, pushMessage, "http://fergl.ie"); response.Append($"Sent: {subscription.Endpoint}"); }); return(response.ToString()); }
public async Task <IActionResult> SendNotification([FromBody] PushMessageViewModel message) { _logger.LogInformation($"Sending targeted push for: {message.Target} - {message.Notification}"); var pushMessage = new WP.PushMessage(message.Notification) { Topic = message.Topic, Urgency = message.Urgency }; // TODO: This should be scheduled in background await _subscriptionStore.ForEachSubscriptionAsync(message.Target, (WP.PushSubscription subscription) => { _logger.LogInformation($"Found subscription: {subscription}"); _notificationService.SendNotificationAsync(subscription, pushMessage, message.Target); }); return(NoContent()); }
private static HttpRequestMessage SetContent(HttpRequestMessage pushMessageDeliveryRequest, PushSubscription subscription, PushMessage message) { HttpContent httpContent = message.HttpContent; if (httpContent is null) { pushMessageDeliveryRequest.Content = null; } else { AsymmetricCipherKeyPair applicationServerKeys = ECKeyHelper.GenerateAsymmetricCipherKeyPair(); byte[] applicationServerPublicKey = ((ECPublicKeyParameters)applicationServerKeys.Public).Q.GetEncoded(false); pushMessageDeliveryRequest.Content = new Aes128GcmEncodedContent( httpContent, GetKeyingMaterial(subscription, applicationServerKeys.Private, applicationServerPublicKey), applicationServerPublicKey, CONTENT_RECORD_SIZE ); } return(pushMessageDeliveryRequest); }
private static HttpRequestMessage SetUrgency(HttpRequestMessage pushMessageDeliveryRequest, PushMessage message) { switch (message.Urgency) { case PushMessageUrgency.Normal: break; case PushMessageUrgency.VeryLow: case PushMessageUrgency.Low: case PushMessageUrgency.High: pushMessageDeliveryRequest.Headers.Add(URGENCY_HEADER_NAME, _urgencyHeaderValues[message.Urgency]); break; default: throw new NotSupportedException($"Not supported value has been provided for {nameof(PushMessageUrgency)}."); } return(pushMessageDeliveryRequest); }
private static HttpRequestMessage SetTopic(HttpRequestMessage pushMessageDeliveryRequest, PushMessage message) { if (!String.IsNullOrWhiteSpace(message.Topic)) { pushMessageDeliveryRequest.Headers.Add(TOPIC_HEADER_NAME, message.Topic); } return(pushMessageDeliveryRequest); }
private HttpRequestMessage PreparePushMessageDeliveryRequest(PushSubscription subscription, PushMessage message, VapidAuthentication authentication, VapidAuthenticationScheme authenticationScheme) { authentication = authentication ?? DefaultAuthentication; if (authentication == null) { throw new InvalidOperationException("The VAPID authentication information is not available"); } HttpRequestMessage pushMessageDeliveryRequest = new HttpRequestMessage(HttpMethod.Post, subscription.Endpoint) { Headers = { { TTL_HEADER_NAME, (message.TimeToLive ?? DefaultTimeToLive).ToString(CultureInfo.InvariantCulture) } } }; pushMessageDeliveryRequest = SetAuthentication(pushMessageDeliveryRequest, subscription, authentication, authenticationScheme); pushMessageDeliveryRequest = SetUrgency(pushMessageDeliveryRequest, message); pushMessageDeliveryRequest = SetTopic(pushMessageDeliveryRequest, message); pushMessageDeliveryRequest = SetContent(pushMessageDeliveryRequest, subscription, message); return(pushMessageDeliveryRequest); }
/// <summary> /// Requests delivery of push message by push service as an asynchronous operation. /// </summary> /// <param name="subscription">The push service subscription.</param> /// <param name="message">The push message.</param> /// <param name="authentication">The authentication details.</param> /// <param name="authenticationScheme">The <see cref="VapidAuthenticationScheme"/> to use.</param> /// <param name="cancellationToken">The cancellation token to cancel operation.</param> /// <returns>The task object representing the asynchronous operation.</returns> public async Task RequestPushMessageDeliveryAsync(PushSubscription subscription, PushMessage message, VapidAuthentication authentication, VapidAuthenticationScheme authenticationScheme, CancellationToken cancellationToken) { HttpRequestMessage pushMessageDeliveryRequest = PreparePushMessageDeliveryRequest(subscription, message, authentication, authenticationScheme); HttpResponseMessage pushMessageDeliveryRequestResponse = null; try { pushMessageDeliveryRequestResponse = await _httpClient.SendAsync(pushMessageDeliveryRequest, HttpCompletionOption.ResponseHeadersRead, cancellationToken); int retriesAfterCount = 0; while (ShouldRetryAfter(pushMessageDeliveryRequestResponse, retriesAfterCount, out TimeSpan delay)) { pushMessageDeliveryRequest.Dispose(); pushMessageDeliveryRequestResponse.Dispose(); await Task.Delay(delay, cancellationToken); pushMessageDeliveryRequest = PreparePushMessageDeliveryRequest(subscription, message, authentication, authenticationScheme); pushMessageDeliveryRequestResponse = await _httpClient.SendAsync(pushMessageDeliveryRequest, HttpCompletionOption.ResponseHeadersRead, cancellationToken); retriesAfterCount++; } await HandlePushMessageDeliveryRequestResponse(pushMessageDeliveryRequestResponse, subscription); } finally { pushMessageDeliveryRequest.Dispose(); pushMessageDeliveryRequestResponse?.Dispose(); } }
/// <summary> /// Requests delivery of push message by push service as an asynchronous operation. /// </summary> /// <param name="subscription">The push service subscription.</param> /// <param name="message">The push message.</param> /// <param name="authentication">The authentication details.</param> /// <param name="cancellationToken">The cancellation token to cancel operation.</param> /// <returns>The task object representing the asynchronous operation.</returns> public Task RequestPushMessageDeliveryAsync(PushSubscription subscription, PushMessage message, VapidAuthentication authentication, CancellationToken cancellationToken) { return(RequestPushMessageDeliveryAsync(subscription, message, authentication, DefaultAuthenticationScheme, cancellationToken)); }
/// <summary> /// Requests delivery of push message by push service as an asynchronous operation. /// </summary> /// <param name="subscription">The push service subscription.</param> /// <param name="message">The push message.</param> /// <param name="authentication">The authentication details.</param> /// <param name="authenticationScheme">The <see cref="VapidAuthenticationScheme"/> to use.</param> /// <returns>The task object representing the asynchronous operation.</returns> public Task RequestPushMessageDeliveryAsync(PushSubscription subscription, PushMessage message, VapidAuthentication authentication, VapidAuthenticationScheme authenticationScheme) { return(RequestPushMessageDeliveryAsync(subscription, message, authentication, authenticationScheme, CancellationToken.None)); }
/// <summary> /// Requests delivery of push message by push service as an asynchronous operation. /// </summary> /// <param name="subscription">The push service subscription.</param> /// <param name="message">The push message.</param> /// <returns>The task object representing the asynchronous operation.</returns> public Task RequestPushMessageDeliveryAsync(PushSubscription subscription, PushMessage message) { return(RequestPushMessageDeliveryAsync(subscription, message, null, DefaultAuthenticationScheme, CancellationToken.None)); }