Where's Waldo: Track user locations with Node.js and Redis
Where's Waldo is my little node.js/Redis project to keep track of users in an app. Say hi!
Tracking hits on every request can get costly, and I didn't want to hold up the more important server processes with this. So, it felt like a good fit for a quick asynchronous web server. Node.js and Redis fit the bill perfectly.
Here's a sample from a development build of my Tender Support product. You can probably tell where I'm going with this...
If you can't tell: you'll be able to see who is reading the same discussion that you're currently on.
First, you track a location of a user. Each
curl call below returns some JSON. The result call I'm showing below is actually output from the example node.js script above.
curl "http://127.0.0.1:3456/waldo/track?location=home&name=rick" TRACK rick => home
Now, you can locate that user:
curl "http://127.0.0.1:3456/waldo/locate?name=rick" LOCATE rick => home
You probably won't be doing this that much, though. Let's list the users in "home" after adding a few more users:
curl "http://127.0.0.1:3456/waldo/track?location=home&name=bob" TRACK bob => home curl "http://127.0.0.1:3456/waldo/track?location=home&name=fred" TRACK fred => home curl "http://127.0.0.1:3456/waldo/list?location=home" LIST home => bob, fred, rick
How's all this work? Each track call stores two redis keys:
waldo:LOCATION:USER. From this, we can see where a user is, and how many users are in a location. In Redis commands, the above might look something like this:
# tracking rick at home SET waldo:rick home SET waldo:home:rick 1 # locate rick GET waldo:rick # returns home # list users at home KEYS waldo:home:* # returns "waldo:home:rick" # track rick at desk DEL waldo:home:rick SET waldo:rick desk SET waldo:desk:rick
Why didn't I use one of the nicer redis data types like a list or a set? I can expire these individual keys. In 5 minutes, the
waldo:home:rick keys are dropped. This keeps the location lists from growing out of hand.
This isn't used in production just yet. I can see a big problem off the bat. The API is easily hackable. I don't know what someone would gain out of it, but you could just plug in your own users and locations and hack the results. I'll probably be adding some kind of token authentication verification to make sure that only confirmed sites can update Waldo.
While working on Waldo, I came across a different implementation of a similar problem: Luke Melia's "Who's Online?" lib. It uses Redis sets to track user IDs, and set unions to determine which of your friends are online. That's another very cool use of Redis.