Divide by zero
# Wednesday, June 11, 2008
Where are your blog visitors coming from in DasBlog?

See part II of this post here.

By combining the Google Maps API with an IP address host service such as HostIP.info, it is possible to present a map showing the current visitors to your blog, and to display them on a map. This implementation shows how to do this for dasBlog. The result will look something like this:

Notice that the shadow on the marker for the united States is darker, indicating more hits for that area. Each of the marker icons can be clicked to give location details and how many hits for that location.

Client side or server side location determination

The location of an IP Address can be determined at the server side, or at the client side. Each has its advantages and disadvantages. A brief but not complete list of pros and cons is:

  • Client side
    • Pros
      • No delay in serving the page as the processing is done after the page has been serves to the client.
      • Easy to implement
    • Cons
      • Requires a call to a web service on a different domain which will cause security concerns
      • Does not allow for users to be able to modify what is their perceived location
  • Server side
    • Pros
      • More control as you are not dependent on an external web service
      • It is easier to cache results if required
    • Cons
      • More difficult to implement, especially if you want to keep to the architecture of the software you are developing for
      • You must maintain and update your own databse of IP address ranges and locations
The client side solution

This solution relies on a client side solution, taking advantage of the excellent Prototype JavaScript Framework. Further down the track I might possibly change this to a server side solution, but as it is only for an administrative page it is not so important. Note that there are security concerns with doing this client side. It is necessary top make an AJAX call to an external webservice, and this could be malicious, especially if a site were hacked. In order to view the example for this, you would have to add http://blog.focas.net.au to your trusted zones in Internet Explorer. If you do this, please make sure you remove it immediately afterwards. Usually I would only add a trusted site if I were using it frequently. The example page can be viewed at Visitors.aspx (Please scroll down to the bottom of the page as there are styling issues. The page may need refreshing)

I created a server page called Visitors.aspx, and a user control called VisitorsBox.ascx. These are directly based upon Referrers.aspx and ReferrersBox.ascx in the standard DasBlog source code.

How it works

C# code in the page creates JavaScript which is then registered with the RegisterClientScriptBlock method of the ClientScript object. The javascript requires some dynamic variables to be created and this is why it is in the page. Also the way dasBlog is set-up seems to make it difficult to add JavaScript to just one page without using this method. Atwo dimensional array is created which contains unique IP addresses and a count of hits for those addresses. THis is then processed on the client side The JavaScript code to create the map follows, it is well documented in the Google Maps API documentation, so i won't say too much about it.
     
if (GBrowserIsCompatible()) {
     map = new GMap2(document.getElementById('map_canvas'));
     map.setCenter(new GLatLng(37.4419, -122.1419), 1);
     var mapTypeControl = new GMapTypeControl();
     var topRight = new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10,10));
     var bottomRight = new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(10,10));
     map.addControl(mapTypeControl, topRight);
     map.addControl(new GSmallMapControl());

Now we need to loop thru the IP address array and call the hostip.info page to get the city/state/country information. There are different calls that can be made to return HTML or XML. I used the HTML version as it is a smaller response, and easy to parse with regular expressions. If there is no information for an IP address it will return (Unknown). Thed regular expression trims them out. This database seems to be maintained by one person, so consider donating to them.

var myAjax;
      
 for (var x=0;x<addresses.length;x++) {
     myAjax = new Ajax.Request('http://api.hostip.info/get_html.php?ip=' + addresses[x][0] , 
     {
         method: 'get', 
         onSuccess: function(originalRequest) {
            var result=originalRequest.responseText;
            var tokens=result.split('\n');
            var count=addresses[x][1];
            var country=/\:[^\(]+/i.exec(tokens[0])[0].substring(1).strip();
            var city=/\:[^\(]+/i.exec(tokens[1])[0].substring(1).strip();
            var location=(city.length>0)? city + ',':'';
             location+=country;     
            varmessage=location + ': ' + addresses[x][1] + ' visitor';
            if (addresses[x][1] > 1) message+='s';
		

 Now we can call the GClientGeocoder object to turn the city/state/country information into a latitude/longtitude combination. The GClientGeocoder's getLatLng object expects a method to be passed in to handle a callback. In this code, it is used to create the marker on the map which can be clicked to view more information.

   var geocoder = new GClientGeocoder();
   geocoder.getLatLng(location,
   function(point) {  
      if (point) { 
         var marker = new GMarker(point);   
         map.addOverlay(marker);   
         GEvent.addListener(marker, 'click', function() {
         marker.openInfoWindow(message);
      });
   }
   });
		

This javascript is created in the C# code using a StringBuilder object, and is then added to the page using the RegisterClientScriptBlock method of the ClientScript object.

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "ipaddressdata", sb.ToString(), true);

Download

The download code contains the Visitors.aspx and Visitors.ascx page and component. These should be dropped into the newtelligence.DasBlog.Web folder of your dasBlog source code. Before going any further you will need to change the Google Maps key in VisitorsBox.ascx.cs file.

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "googlemaps",
    @"<script src='http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOUR KEY GOES HERE'"+" type='text/javascript'></script>");
		

When you have compiled the code, drop those two files into the root of your website, and the newtelligence.DasBlog.Web.dll into the bin folder of your website. Remember to change the trust settings for your blog, and enjoy seeing who is visiting your site. Note that the Google Maps JavaScript and Prototype JavaScripts are served up from the Google servers so you don't need to download them.

Visitors.zip (10.57 KB)


Wednesday, June 11, 2008 11:53:11 PM (AUS Eastern Standard Time, UTC+10:00)   #    Comments [0]  Downloads | JavaScript | WebmasterTracked by:
"Using VisiFire to create a Silverlight chart of your visitors in dasBlog " (Cat... [Trackback]

link to del.icio.us link to reddit link to StumbleUpon link to Facebook Bookmark to Google
OpenID
Please login with either your OpenID above, or your details below.
Name
E-mail
Home page

Comment (Some html is allowed: a@href@title, b, em, i, strike, strong, u) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview