Let’s say you play a multiplayer game online that provides updates via a Twitter stream. Let’s say it’s a game like QONQR. Now, you may be a little bit addicted to playing that game. I’m not saying I know anyone that is, but if someone was, they may want to consume that Twitter stream and do some fun things with the information. You could mess around with some kind of traditional polling client, but Twitter has a Streaming API available, so why not use that? Of course, if you were going to write some cool new app to leverage that data, you would certainly test it out on Windows 8, right?
Conceptually, the idea seems pretty straightforward. I want to consume the Http Stream on a continuous basis, and update my application as new tweets are received. A couple things complicate this idea. First, we usually deal with Http requests in a connect-request-receive-disconnect approach. Get in, get out. So how do we keep a connection open to the server that we can read from continually? Second, in Windows 8, all of the network operations are asynchronous, so how do we get the updates from the async operation back to the UI?
First, we will create class to handler the streaming. In trail blazing fashion, I will name this class HttpStreaming. Because of problem #2, I know that any work that is done by the HttpStreaming class will most likely need to be marshaled back on the UI thread. In my simple app, all I want to do is read in Tweets and add them into a GridView control. My class starts of looking like this:
public class HttpStreaming
{
CoreDispatcher _dispatcher;
public HttpStreaming(CoreDispatcher dispatcher)
{
_dispatcher = dispatcher;
}
}
The HttpStreaming class asks for the Dispatcher associated with the application’s UI thread. We’ll see how to that shortly.
Now, it is time for the meat of the problem. Accessing and processing the Http stream. The basic operation looks like this:
public void Start(Action<JsonObject> action)
{
try {
var webRequest = (HttpWebRequest) WebRequest.Create("https://stream.twitter.com/1/
statuses/filter.json?follow=255956231");
webRequest.Credentials = new NetworkCredential("user","password");
webRequest.BeginGetResponse((callback) => {
try {
Encoding encode = Encoding.GetEncoding("utf-8");
var request = callback.AsyncState as HttpWebRequest;
var response = request.EndGetResponse(callback) as HttpWebResponse;
while (true)
{
try
{
var responseStream = new StreamReader(response.GetResponseStream(), encode);
var json = responseStream.ReadLine();
var data = JsonObject.Parse(json);
if (action != null && data != null)
{
_dispatcher.InvokeAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
(s, e) =>
{
action(data);
},
this,
null);
}
}
catch (IOException ex) { }
catch (OutOfMemoryException ex) { }
}
}
catch (WebException ex) {}
catch (IOException ex) {}
catch (OutOfMemoryException ex) {}
catch (Exception ex) {}
},webRequest);
}
catch (WebException ex) {}
}
There is a lot going on here, so let’s break it down because it is really not that complicated. First, the Start method accepts an Action that expects to get a JsonObject passed to it. This makes sense since the Twitter stream will be feeding us Json representations of the tweets.
Next, we set up the HttpWebRequest. Twitter requires authentication to access the stream, so you can omit this if yours does not. We start the async request by calling BeginGetResponse. The callback lamda expression does all of the processing. The heart is the continual while loop. The only time we break out of the loop is if there is an Exception.
The loop does continually reads from the Http Stream, and if there is a json object, it uses the dispatcher to call the Action. I’ll leave it up to you on how to handle the various exceptions.
In the the code-behind of my application’s page I put this code:
HttpStreaming httpStream;
ObservableCollection<string> tweetList = new ObservableCollection<string>();
public BlankPage()
{
this.InitializeComponent();
tweetView.ItemsSource = tweetList;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
httpStream = new HttpStreaming(this.Dispatcher);
httpStream.Start((json) => {
var tweetText = json.GetNamedString("text");
tweetList.Add(tweetText);
});
}
When the page is navigated to, it sets up the HttpStreaming object with the Dispatcher and then connects to the stream. You could set this up differently to suit the needs of your application. In my demo app, I have created an ObservableCollection that will hold the tweets that I want updated on my page. The Action assigned to the Start method simply takes the returned json object, pulls the text value, and inserts the text string into the ObservableCollection.
All in all, it is pretty straightforward stuff, but not intuitively obvious. At least it wasn’t for me. You may find it useful in this world of web connected software. Now, let’s see if I can figure it out in javascript. Stay tuned…
Note: Special thanks to Shannon Whitley that got me pointed in the right direction when I first thought about this problem with his helpful blog post - Open Source .NET (C#) Twitter Streaming API Client