A Nixie Tube Web counter?
For a while I’ve been trying to come up with another nixie tube project, and then one afternoon in May I got this great idea to create a web counter for smbaker.com using nixie tubes. The first task was to pick which kind of tube to use. Either IN-14 or IN-12 were the most likely candidates. IN-14 are traditional vertical-mount tubes, IN-12 are a horizontal-mount tube. As the end goal is to put this in a rackmount case, I chose to go the IN-12 route. Another nice property of the IN-12 is that they use sockets, rather than the IN-14, which have to be wired in directly.
Some might ask why one would want a nixie tube web counter? After all, a web counter can simply be run on your desktop. The type of person who would ask such a question probably isn’t reading this page, so let’s get on with the job of building this thing…
Off to find some IN-12 Nixies…
I headed off to the usual place (ebay) to find some tubes, and I came across a great IN-12 “clock/counter” kit from kosbo.com. It’s a 10-digit kit that uses In-12 tubes. The height is nice and short, so it would fit well in a 2U rackmount case. The one listed on ebay was a completed “clock”, but I wanted to DIY, so I contacted Konstantin at kosb.com, and he was able to give me a slight discounted for an unassembled kit. Usually I would have preferred to design the display modules myself (and I have a few designs waiting at batchPCB to try out), but this nice kit was too good of a deal to pass up.
So now we have a counter module, but we still need to interface it with the web so it can pull stats from the web server. For this task, I chose to use one of my generic propeller boards. These boards I originally designed for my “NTPClock” but I’ve repurposed them a number of times, including for the packetron-9000. My generic board includes a 8-core propeller microcontroller, and a ENC28J60 ethernet controller and magjack. It’s perfect for the task of downloading the from the server and sending the controls to Kosbo’s clock/counter board.
Below you can see the innards of the web counter. The short two-PCB stack near the front with the 10 tubes is the kosbo clock/counter. The rectangular green board is my propeller board. There’s also a small 9VDC transformer, and some toggle switches. Pretty simple so far.
Instrumenting the web server
This is a two-part project. The web server is going to need to be instrumented to do the actual counting. When a web access occurs, the server will increment the count, and send a packet “home” to the counter to tell it to update itself. This is a push approach. An alternative would be a polling approach where the counter would poll the server periodically to get the current counter. Either alternative is valid. The push approach has the advantage that web hits immediately show up on the counter. The pull approach has the disadvantage that a hit would have to wait until the next poll before it is noticed.
Next I had to choose the transport protocol. The obvious choices are TCP and UDP. TCP is reliable but has more overhead associated with it, and has to wait during connection establishment. UDP is a ‘fire and forget’ protocol. You just send off a packet and it either makes it or it doesn’t. We don’t need reliability with a web counter, so I chose to go with less overhead and use UDP. Whenever a hit occurs, it blasts one UDP packet home, where it will be picked up by the web counter. If a packet is dropped (remember, UDP is unreliable) then we will miss that hit. However, as the server is doing the actual counting, the server will still count the hit; it’s just the notification that will be lost, and the counter would receive the correct count the next time a UDP packet makes it through.
As smbaker.com uses wordpress, instrumenting the server should be as simple as writing a wordpress module. After a page is displayed, count, and send the UDP packet.
Getting the data from the server to the counter
The first problem I encountered was the cheap GoDaddy hosting package that I use. It doesn’t allow me to run arbitrary CGI scripts, or to use “sockets” in PHP. This means there was no way for me to easily send that UDP packet from the server to the counter.
My first attempt was to use by other server, an ancient cobalt RAQ which does allow me to send packets to arbitrary addresses and sockets. I wrote the following simple python script:
#! /usr/bin/python import os import sys import socket sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: i = int(open("hitcounter.txt","r").read()) except: i = 0 i = i + 1 open("hitcounter.txt", "w").write(str(i)) address = ("50.137.49.26", 0x1116) buf = chr(i >> 24) + chr((i >> 16) & 0xFF) + chr((i >> 8 ) & 0xFF) + chr(i & 0xFF) sock.sendto(buf, address) print "content-type: image/gif" print "" sys.stdout.write("GIF89a\x01\x00\x01\x00\x80\x00\x00\xdb\xdf\xef\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;")
The above script is intended to be used as an inline image from any web page. It stores the counter in a simple text file, then it sends off the magic UDP packet, and finally it outputs the binary content of a 1-pixel GIF file. I then included an IMG tag to this image in my wordpress template, and the counter was working.
A wordpress solution
The above script worked, but it wasn’t a very elegant solution (particularly since I had to locate it on a second server that allowed arbitrary packets to be sent).
I figured, now is as good a time as any to bite the bullet and upgrade to a Godaddy Virtual Dedicated Server, so I pulled the trigger and ordered one of these. Smbaker.com as a result is now hosted on a modern centos 6.2 virtual server, all of my other web providers have been terminated and the content aggregated here. As a side benefit, I’m now able to send packets to arbitrary UDP addresses using a native wordpress addon.
So, let’s take a look at this addon:
<?php /* Plugin Name: Scotts Hit Counter Plugin URI: http://none/ Description: The Hit counter Version: 1.0 Author: Dr. Scott Michael Baker Author URI: http://www.smbaker.com/ */ function scotts_hitcounter_footer() { $options = get_option("widget_scotts_hitcounter"); if (empty($options)) { $count = 0; } else { $count = $options['count']; } $count = $count + 1; $options["count"] = $count; update_option('widget_scotts_hitcounter', $options); //echo $count; $buf = chr($count>>24) . chr($count>>16 & 0xFF) . chr($count>>8 & 0xFF) . chr($count & 0xFF); $sock = socket_create(AF_INET, SOCK_DGRAM, 0); socket_sendto($sock, $buf, 4, 0, my_ip_address, my_port); } add_action('footer', 'scotts_hitcounter_footer'); ?>
This script is pretty simple. It attaches itself to the wordpress footer action, so that every time the footer of a page is displayed, it runs. A counter is retrieved from the database, incremented, stored in the database, and sent off via UDP to the counter.
PHP Sockets are used to send the packets. It works great, right from wordpress. So far, it’s proven to be quite reliable.
Coding up the webcounter itself
to be continued…