The following code works with Window Phone 8.0, but deadlocks on
int nextByte = stream.ReadByte();
in Windows Phone 8.1:
/// <summary>
/// Performs a query on the Twitter Stream.
/// </summary>
/// <param name="request">Request with url endpoint and all query parameters.</param>
/// <returns>
/// Caller expects an JSON formatted string response, but
/// real response(s) with streams is fed to the callback.
/// </returns>
public async Task<string> QueryTwitterStreamAsync(Request request)
{
WriteLog(request.FullUrl, "QueryTwitterStreamAsync");
var handler = new HttpClientHandler();
if (Authorizer.Proxy != null && handler.SupportsProxy)
handler.Proxy = Authorizer.Proxy;
using (StreamingClient = new HttpClient(handler))
{
StreamingClient.Timeout = TimeSpan.FromMilliseconds(System.Threading.Timeout.Infinite);
var httpRequest = new HttpRequestMessage(HttpMethod.Post, request.Endpoint);
var parameters =
string.Join("&",
(from parm in request.RequestParameters
select parm.Name + "=" + Url.PercentEncode(parm.Value))
.ToList());
var content = new StringContent(parameters, Encoding.UTF8, "application/x-www-form-urlencoded");
httpRequest.Content = content;
var parms = request.RequestParameters
.ToDictionary(
key => key.Name,
val => val.Value);
SetAuthorizationHeader(HttpMethod.Post, request.FullUrl, parms, httpRequest);
httpRequest.Headers.Add("User-Agent", UserAgent);
httpRequest.Headers.ExpectContinue = false;
if (Authorizer.SupportsCompression)
httpRequest.Headers.AcceptEncoding.TryParseAdd("gzip");
var response = await StreamingClient.SendAsync(
httpRequest, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
await TwitterErrorHandler.ThrowIfErrorAsync(response).ConfigureAwait(false);
Stream stream = await CreateStream(response);
const int CarriageReturn = 0x0D;
const int LineFeed = 0x0A;
var memStr = new MemoryStream();
while (stream.CanRead && !IsStreamClosed)
{
**int nextByte = stream.ReadByte();**
if (nextByte == -1) break;
if (nextByte != CarriageReturn && nextByte != LineFeed)
memStr.WriteByte((byte)nextByte);
if (nextByte == LineFeed)
{
int byteCount = (int)memStr.Length;
byte[] tweetBytes = new byte[byteCount];
memStr.Position = 0;
await memStr.ReadAsync(tweetBytes, 0, byteCount).ConfigureAwait(false);
string tweet = Encoding.UTF8.GetString(tweetBytes, 0, byteCount);
var strmContent = new StreamContent(this, tweet);
await StreamingCallbackAsync(strmContent).ConfigureAwait(false);
memStr.Dispose();
memStr = new MemoryStream();
}
}
}
IsStreamClosed = false;
return "{}";
}
async Task<Stream> CreateStream(HttpResponseMessage response)
{
var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
if (Authorizer.SupportsCompression)
return new GZipStream(stream, CompressionMode.Decompress);
else
return stream;
}
This is from my open source project, LINQ to Twitter, at:
This is no longer an issue and is largely taken over by events (OBE). I'm no longer targeting Windows 8.1 for streaming support and have moved on to Windows 10, which introduced a new Windows.Web.Http.HttpClient. Streaming works perfectly on all my emulators and Windows 10 devices with the new HttpClient.