/// <summary> /// Sends publish requests to the server. /// </summary> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>A task.</returns> private async Task PublishAsync(CancellationToken cancellationToken = default(CancellationToken)) { var publishRequest = new PublishRequest { RequestHeader = new RequestHeader { TimeoutHint = PublishTimeoutHint, ReturnDiagnostics = this.DiagnosticsHint }, SubscriptionAcknowledgements = new SubscriptionAcknowledgement[0] }; while (!cancellationToken.IsCancellationRequested) { try { var publishResponse = await this.PublishAsync(publishRequest); // Views and view models may be abandoned at any time. This code detects when a subscription // is garbage collected, and deletes the corresponding subscription from the server. var handled = false; foreach (var subscription in this.Subscriptions) { handled |= subscription.OnPublishResponse(publishResponse); } // If event was not handled, if (!handled) { // subscription was garbage collected. So delete from server. var request = new DeleteSubscriptionsRequest { SubscriptionIds = new uint[] { publishResponse.SubscriptionId } }; await this.DeleteSubscriptionsAsync(request); } publishRequest = new PublishRequest { RequestHeader = new RequestHeader { TimeoutHint = PublishTimeoutHint, ReturnDiagnostics = this.DiagnosticsHint }, SubscriptionAcknowledgements = new[] { new SubscriptionAcknowledgement { SequenceNumber = publishResponse.NotificationMessage.SequenceNumber, SubscriptionId = publishResponse.SubscriptionId } } }; } catch (ServiceResultException ex) { Log.Warn($"Error publishing subscription. {ex.Message}"); // short delay, then retry. await Task.Delay((int)DefaultPublishingInterval); } } }
/// <summary> /// Deletes one or more Subscriptions. /// </summary> /// <param name="client">A instance of <see cref="ISessionClient"/>.</param> /// <param name="request">A <see cref="DeleteSubscriptionsRequest"/>.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation that returns a <see cref="DeleteSubscriptionsResponse"/>.</returns> public static async Task<DeleteSubscriptionsResponse> DeleteSubscriptionsAsync(this ISessionClient client, DeleteSubscriptionsRequest request) { if (request == null) { throw new ArgumentNullException("request"); } return (DeleteSubscriptionsResponse)await client.RequestAsync(request).ConfigureAwait(false); }