The Typical Approach...
Here, we’ve defined a function that accepts another function as its main argument and passes the callback function a doubled version of x. Pretty simple, and many libraries use this technique for Ajax calls. Let’s take a minute and spin the globe, though – what if, instead of arbitrarily accepting a function and having to worry about possible scoping issues, we could just announce when an event of interest has occurred, and fire an attached function at that point? This would be so much cleaner than passing around function references everywhere.
The great thing about all this? We can actually do this in Node through use of the events library. This, in many ways, is core to how things in Node work. Everything is event based, so why shouldn’t we be able to fire off our own events? To showcase what’s possible with this, let’s build a basic library to connect to Twitter's Streaming API, which we can then filter results from as we see fit.
The Basics: exporting an EventEmitter instance
Before we get into anything Twitter-specific, we’ll demonstrate basic usage of EventEmitter. The code below shows how simple this can really be – it’s a contrived example that constantly increases numbers by one, and emits an event called “even” every time the number becomes even.
Usage of EventEmitter is pretty simple – you basically want to inherit all the properties from EventEmitter itself into your Object, giving it all the properties it needs to emit events on its own. Events are sent off as keywords (‘even’, ‘error’, etc), called directly on the object. You can extend the prototype chain further, and EventEmitter should work fine and dandy.
Changing Tracks for a Moment...
Now that we’ve shown how EventEmitter works, we want to go ahead and use it for Twitter's Streaming API. For the unfamiliar, the Streaming API is essentially a never ending flood of tweets. You open a connection, and you keep it open; data is pushed to you, reversing the typical model of “request/response” a bit in that you only really make one request. EventEmitter is perfect for this task, but to satisfy some basic needs for interacting with Twitter's API, we’ll need a base library, like what’s shown in the example below:
Here we require the three main resources we’ll need (util, http and events), and set up a new Object that’s essentially an instance of EventEmitter. We’ll throw it over to exports, too, so it plays nicely when relying on it in outside code. Creating instances of our Twitter object requires a few things – ‘track’, which is a keyword to filter tweets by, and a ‘username’/’password’ combination which should be self explanatory (in terms of what they are).
Why ‘username/password’, though? Twitter's Streaming API requires some form of authentication; for the sake of brevity in this article, we’re going to rely on Basic Authentication, but moving forward it’s recommended that you use OAuth for authenticating with Twitter, as it relies on the user granting you privileges instead of actually handing over their password. The OAuth ritual is much longer and more intricate to pull off, though, and would push the length and scope of this article far beyond its intentions.
Emitting a "Tweet" Event
Now that we’ve got the basic scaffolding for our library set up, let’s throw in a function to actually connect, receive tweets, and emit an event or two that other code can catch. Check out the following for a prime example of how we can do this:
If you’ve worked with Node before, this code shouldn’t be too daunting, but we’ll summarize it just in case. We’re extending the prototype of our Twitter object that we created before, and adding a method to start the stream of tweets coming in. We set up an object detailing the host, port, path and method, as well as some custom headers (notably, setting ‘keep-alive’ and Basic Authentication headers). This is passed to an http.request() call, and we then write our tracking data and end the connection.
The response function has some logic to handle putting together tweets that are sent in by Twitter. The API dictates that a tweet object will end on the two characters ‘\r’ and ‘\n’, so we basically walk the built up JSON strings as they come in and separate them out. If a JSON string is successfully pulled out, we emit a ‘tweet’ event, and pass it the parsed JSON data. If something went horribly wrong, we emit an ‘error’ event and pass it the associated object.
Usage and Application
Alright, so now we should have a pretty functional library once we put those two together. The code below shows how we can now use this library in a simple script.
Wrapping Things Up
EventEmitter is an excellent, easy to implement option for dealing with cases where you might want to defer an action until data is ready. Readers with further questions should check out the Node.js documentation on EventEmitter. The source code for this article is included in the full, zipped up magazine download, as well as mirrored at the following link.
- Source Code & Listings
- Node.js Events Documentation
- Twitter Streaming API Docs