public async Task LongPollUserEvents(string streamPosition,
Action<BoxEventCollection<BoxEnterpriseEvent>> newEventsCallback,
CancellationToken cancellationToken,
UserEventsStreamType streamType = UserEventsStreamType.all,
bool dedupeEvents = true,
int? retryTimeoutOverride = null)
{
const string NEW_CHANGE_MESSAGE = "new_change";
string nextStreamPosition = streamPosition;
while (true)
{
BoxRequest optionsRequest = new BoxRequest(_config.EventsUri)
.Param("stream_type", streamType.ToString())
.Method(RequestMethod.Options);
IBoxResponse<BoxLongPollInfoCollection<BoxLongPollInfo>> optionsResponse = await ToResponseAsync<BoxLongPollInfoCollection<BoxLongPollInfo>>(optionsRequest).ConfigureAwait(false);
var longPollInfo = optionsResponse.ResponseObject.Entries[0];
var numRetries = Int32.Parse(longPollInfo.MaxRetries);
bool pollAgain = true;
do
{
if (cancellationToken.IsCancellationRequested)
{
cancellationToken.ThrowIfCancellationRequested();
}
try
{
var timeout = retryTimeoutOverride.HasValue ? retryTimeoutOverride.Value : longPollInfo.RetryTimeout;
BoxRequest pollRequest = new BoxRequest(longPollInfo.Url) { Timeout = TimeSpan.FromSeconds(timeout) };
IBoxResponse<BoxLongPollMessage> pollResponse = await ToResponseAsync<BoxLongPollMessage>(pollRequest).ConfigureAwait(false);
var message = pollResponse.ResponseObject.Message;
if (message == NEW_CHANGE_MESSAGE)
{
BoxEventCollection<BoxEnterpriseEvent> newEvents = null;
do
{
newEvents = await UserEventsAsync(streamType: streamType, streamPosition: nextStreamPosition, dedupeEvents: dedupeEvents).ConfigureAwait(false);
nextStreamPosition = newEvents.NextStreamPosition;
if (newEvents.Entries.Count > 0)
{
newEventsCallback.Invoke(newEvents);
}
} while (newEvents.Entries.Count > 0);
}
}
catch
{
//Most likely request timed out.
//If we've reached maximum number of retries then bounce all the way back to the OPTIONS request.
pollAgain = numRetries-- > 0;
}
} while (pollAgain);
}
}
}