/// <summary>
        /// Requests the Server to return a NotificationMessage or a keep-alive Message.
        /// </summary>
        /// <param name="client">A instance of <see cref="ISessionClient"/>.</param>
        /// <param name="request">A <see cref="PublishRequest"/>.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation that returns a <see cref="PublishResponse"/>.</returns>
        public static async Task<PublishResponse> PublishAsync(this ISessionClient client, PublishRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            return (PublishResponse)await client.RequestAsync(request).ConfigureAwait(false);
        }
        /// <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);
                }
            }
        }