I am writing some code to test some Wowza streams by making HTTP calls to various URLs related to the stream and checking for a 200 status. I wrote a simple method to call httpClient.GetAsync and return a test result:
public async Task<TestResult> DoHttpGetTestAsync(string name, string url)
{
if (string.IsNullOrEmpty(url)) return new TestResult { TestName = name, Status = "Skipped", Description = "No url" };
try
{
var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode) return new TestResult { TestName = name, Status = "Success", Description = response.StatusCode.ToString() + ' ' + url };
return new TestResult { TestName = name, Status = "Failed", Description = response.ReasonPhrase + ' ' + url };
}
catch (Exception ex)
{
return new TestResult { TestName = name, Status = "Failed", Description = ex.Message + ' ' + url };
}
}
I then use this to test a handful of URLs:
if (camera.SupportsHighRes) results.Add(await DoHttpGetTestAsync("Get high res Wowza Status", cameraUrls.HighResStatusUrl, "normal"));
if (camera.SupportsLowRes) results.Add(await DoHttpGetTestAsync("Get low res Wowza Status", cameraUrls.LowResStatusUrl, "normal"));
if (camera.SupportsLowRes) results.Add(await DoHttpGetTestAsync("Get low res thumbnail", cameraUrls.LowResThumbnailUrl));
if (camera.SupportsHighRes) results.Add(await DoHttpGetTestAsync("Get high res thumbnail", cameraUrls.HighResThumbnailUrl));
These work as expected. However if I add a call to the HLS feed:
if (camera.SupportsLowRes) results.Add(await DoHttpGetTestAsync("Get low res HLS feed", cameraUrls.LowResHLSFeedUrl));
if (camera.SupportsHighRes) results.Add(await DoHttpGetTestAsync("Get high res HLS feed", cameraUrls.HighResHLSFeedUrl));
Then the previous calls to get status and thumbnails timeout more, throwing a TaskCanceledException. It is as though getting the HLS feed interferes with the other calls and causes them to never complete. Note I am not processing the HLS at all - just checking for a 200 to come back. Looking at it in Fiddler I see this response from the HLS call:
HTTP/1.1 200 OK
Access-Control-Expose-Headers: Date, Server, Content-Type, Content-Length
Access-Control-Allow-Headers: Content-Type, User-Agent, If-Modified-Since, Cache-Control, Range
Date: Thu, 26 Oct 2017 18:54:25 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: OPTIONS, GET, POST, HEAD
Content-Type: application/vnd.apple.mpegurl
Access-Control-Allow-Credentials: true
Accept-Ranges: bytes
Server: WowzaStreamingEngine/4.5.0
Cache-Control: no-cache
Content-Length: 125
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=276673,CODECS="avc1.77.31",RESOLUTION=427x240
chunklist_w684280577.m3u8
I don't see any redirect or anything that I would suspect of causing HttpClient to get bogged down.
I would suspect some bug with Wowza or throttling of some sort, except that if I use a unique instance of HttpClient, I do not see the problem. I've tested by making these calls in a loop both with a shared HttpClient and with a HttpClient-per-test.
The code above has timeouts more often with:
static HttpClient client = new HttpClient();
and it has few or no timeouts with:
private HttpClient client = new HttpClient();
The latter is discouraged, however, since it can lead to socket exhaustion under heavy use.
What about this would cause HttpClient to timeout more often?