Category Archives: Web

Creating a Live Score Board Client Logic

Let us start with a script tag that will enclose all the fundooo script. You can save in a .js file as well if you want…

The httpObj is the XMLHttpRequest object, and xmlScore is the response XMLDocument. I’ve created a player object class which is used by the tplayers variable.

<script type="text/javascript">
var httpObj, xmlScore, players;
function getScore(round, category, sex, player) {
	url = "http://localhost/score_server.php";
	url += "?round="+round+"&category="+escape(category)+
		"&sex="+escape(sex)+"&player="+escape(player)+"&rand="+new Date() ;
	httpObj = false;
    // branch for native XMLHttpRequest object
    if(window.XMLHttpRequest) {
    	try {
			httpObj = new XMLHttpRequest();
        } catch(e) {
			httpObj = false;
        }
    // branch for IE/Windows ActiveX version
    } else if(window.ActiveXObject) {
       	try {
        	httpObj = new ActiveXObject("Msxml2.XMLHTTP");
      	} catch(e) {
        	try {
          		httpObj = new ActiveXObject("Microsoft.XMLHTTP");
        	} catch(e) {
          		httpObj = false;
        	}
		}
    }
	if(httpObj) {
		httpObj.onreadystatechange = processReqChange;
		httpObj.open("GET", url, true);
		httpObj.send(null);

		timerID = setTimeout("getScore('"+round+"', '"+category+"', '"+sex+"', '"+player+"')",30000);
	}
}

The getScore function requires params, that are need for the server. If you notice at the end of the function, the function calls itself again after 30 sec (30,000 msec). Assuming one serve takes half a min or so.

We define the function that will handle the process’ change of status, i.e. when the status turns 4, it assigns xmlScore the XMLDocument object.

function processReqChange() {
    // only if req shows "loaded"
    if (httpObj.readyState == 4) {
        // only if "OK"
        if (httpObj.status == 200) {
            xmlScore = httpObj.responseXML;
			updateScoreBoard();
        } else {
            alert("There was a problem retrieving the XML data:\n" +
                httpObj.statusText);
        }
    }
}

Making a Live Score Board – Client

Here comes the cool part now. The client! using the famous XMLHttpRequest

The basic logic of creating the client is this

  • Make asynchronous calls to the server to fetch the match data
  • Parse the XML data
  • Using DOM update the content of the Score board
  • And obviously add a timer to refresh the asynchronous HTTP calls


It should look something like this.
Score card screenshot

The first time you load the page (most probably it should be a small pop-up window) you can write the basic HTML…
and the main HTML would be something like this.

<div id="scoreboard">

<p style='font-weight:bold;'>
<span id="matchsex">Womens</span> <span id="matchround">Semifinal</span>: 
<span id="player1">Hingis</span> vs <span id="player1">Sharapova</span> 
(<span id="elapsedtime">1.5h</span>)</span> 
</p>

<table style="border-collapse:collapse;" border="1" bordercolor="#888888" 
cellspacing="0" cellpadding="5">
	<tr>
		<td align="left" > </td>
		<td colspan="3" align="left" >Sets</td>
		<td align="left" >Game</td>
	</tr>
	<tr>
		<td align="left" id="matchplayer1">Hingis </td>
		<td align="center" id="setplay1">6</td>
		<td align="center" id="setplay2">3</td>
		<td align="center" id="setplay3">4</td>
		<td align="center" id="gamepoints1">30</td>
	</tr>
	<tr>
		<td align="left" id="matchplayer2">Sharapova</td>
		<td align="center" id="setplay1">4</td>
		<td align="center" id="setplay2">6</td>
		<td align="center" id="setplay3">2</td>
		<td align="center" id="gamepoints2">15</td>
	</tr>
</table>

</div>

Let us consider some important IDs (the id attributes) that we’ve used

  • matchsex: To set the type of match women’s, men’s, etc.
  • matchround: Quarter final, semi final, etc
  • player1, player2: Player’s names id
  • elapsedtime: Elapsed Time
  • matchplayer1, matchplayer2: Score Board’s Player’s name
  • serving: If the player is serving
  • setplay1, setplayx: Playerx’s set
  • gamepoints1, gamepoints2: Player1 and 2’s gamepoints

Creating a Live Score Board

Many a times you may have come across a fancy “Live Score Board”, recently (as of writing) you may have seen the “Java Applet”ized score board. If you want to have a similar such app, but don’t want to get into Java and applets. You may wonder.

But there is a solution, Asynchronous Javascript HTTP Request calls, you may commonly now it AJAX, or famous as XMLHttpRequest

… and make something like
Score board screenshot

You can find working example here, Live Score Board

For your live Score Board App, you need following .

  • A Score Server, which gives scores in a specific format, ideally XML
  • A Client that requests the Server, and displays the parsed XML

We need a Server or a web Service, that will give us the requested data. We’ll use XML to output the response of the server.
We’ll structure the XML as follows

<?xml version="1.0"?>
<scores xmlns="http://www.ruturaj.net/tutorials/php">
<match elapsedtime="1.5h" round="semifinal" category="singles" sex="women">
	<player name="Hingis" serving="1">
		<set no="1">6</set>
		<set no="2">3</set>
		<set no="3">4</set>
		<gamepoints>30</gamepoints>
	</player>
	<player name="Sharapova">
		<set no="1">4</set>
		<set no="2">6</set>
		<set no="3">2</set>
		<gamepoints>15</gamepoints>
	</player>
</match>
</scores>

Assume that we have a database, which is fed continuously. Say we access the above data using the URL as.. http://www.ruturaj.net/tennis/score_server.php?round=semifinal&category=singles&sex=women&player=hingis

Here is a test score_server.php script for testing.

<?php

$array_points = array(15, 30 , 40);
$gamepoints1 = array_rand($array_points, 1);
$gamepoints2 = array_rand($array_points, 1);
$xml = '<?xml version="1.0" ?>
<scores xmlns="http://www.ruturaj.net/tutorials/php">
<match elapsedtime="1.5h" round="semifinal" category="singles" sex="women">
	<player name="Hingis" serving="1">
		<set no="1">6</set>
		<set no="2">3</set>
		<set no="3">4</set>
		<gamepoints>'.$array_points[$gamepoints1].'</gamepoints>
	</player>
	<player name="Sharapova">
		<set no="1">4</set>
		<set no="2">6</set>
		<set no="3">2</set>
		<gamepoints>'.$array_points[$gamepoints2].'</gamepoints>
	</player>
</match>
</scores>
';

header("Content-Type: text/xml");
echo ($xml);
?>

Building a Tag Cloud (logic)

Once we have the data we want, we can build the logic to make the cloud.
Here the logic is extremely simple (no wonder I’ve made a tutorial about it).

The idea is to assign a minimum font-size in “pt” to the least occured tag. In our case we have taken 8pt. Since this 8pt size is applicable to the XML tag (our example), whose tag count is 3. We need to find a multiplying factor for all the tags, that will give us their respective font sizes.

The multiplying factor should take into account, the tags count, and the total of the tag count, which in turn is the percentage of occurance for that tag. So if the factor is x, tag count is 3, tag count sum is 58 and font size is 8, the equation would be

(3 / 58) * x = 8
which gives us x as 
x = (58 / 3) * 8

Now this x has to be multiplied to the % factor of that tag,
to get it's font size value

tag[http] = (10 / 58) * ( (58 / 3) * 8 )

so lets go with PHP,

$min_val = min($tags);
$font_multiplier = ($tag_sum / $min_val) * 8;

// assign the the font sizes
foreach($tags as $key => $value) {
  $tags[$key] = ($value / $tag_sum) * $font_multiplier;
}

Now is the time to display the tags, and link it to what ever, The spacing for each tag word would be fixed I’ll keep it 15pt. Its upto your design to change it!

foreach($tags as $key=>$value) {
  echo "<span style='font-size: {$value}pt; font-family: 
        tahoma;'>$key</span><span style='font-size: 15pt; font-family: 
        tahoma;'>  </span>";
}

Building a Tag Cloud

You may have come across Del.icio.us Tags, which is commonly referered as a “Tag cloud”
tag cloud

It is extremely easy to build such a cloud, all you need to have is to have tags associated with your posts, comments, blogs, etc.

Consider you have a table of posts called POSTS, and another one of TAGS, something like below.

posts
* post_id
* tag_id
* post_content

tags
* tag_id
* tag_name

We need to get the count of tags, and the no. of times that tag has been associated. The query would be.

select a.tag_name, count(b.post_id) tag_count
from tags a, posts b
where a.tag_id = b.tag_id
group by b.tag_id
order by a.tag_name

This will give us a result like this

AJAX, 15
HTTP, 10
Web, 30
XML, 3

Let us decide a minimum font size for the tag, let us take the value of 8pt as the smallest font possible, All that remains is to calculate the font sizes.

We’ll grab the result set first and get the sum of tag count.

$tags = array();
$tag_sum = 0;
while ($row = mysql_fetch_object($res)) {
  $tags[$row->tag_name] = $row->tag_count;
  $tag_sum = $tag_sum + $row->tag_count;
}

// just make a copy of the tags array
$tags_copy = $tags;

Search Engine Referer Keyword Tracking

You really want to analyze your source of traffic. Most of the times you install, use some of the free softwares available on the net. But If you are a programmer… You will want to know how to track these visitors, Search engine keywords, etc…

Here I’ll be showing the programmer’s point of view to develop a solution.

To track most of the important aspects of search engine referals, are the HTTP_REFERER and the HTTP_USER_AGENT variables.

I’m assuming you have Apache as the web server and PHP as the scripting language with my favourite MySQL as the database server.

There are two ways that you can track the above content

  • Apache access logs
  • Database logging

Keyword Hits
So the final result would be like

Keyword Hit Count
keyowrd 1 100
keyowrd 2 70
keyowrd 3 60

Search Engine Referers
Search Engine hit counts

Search Engine Ref. Count
Google 100
Yahoo 70
MSN 60

In this tutorial, I’ll be focussing on the MySQL logging. So lets begin with it.

Firefox 1.5 released

Firefox 1.5
The latest version of Firefox, ie Firefox 1.5 (DeerPark) has been released with a new home. Mozilla.com

Here are some of the features in Firefox 1.5

  • Firefox 1.5 provides easier navigation for everyone, including those who are visually or motor-impaired. Firefox is now the first browser to support DHTML accessibility, which enables Web content to be read aloud – even new kinds of graphics-rich content. Users may navigate with keystrokes rather than mouse clicks, reducing the tabbing required to navigate documents such as spreadsheets. Firefox 1.5 is also the first browser to meet government requirements that software be easily accessible to users with physical impairments.
  • Clear Private Data, Protect your privacy with the new Clear Private Data tool. With a single click, you can delete all personal data, including browsing history, cookies, web form entries and passwords.
  • New support for Web Standards including SVG, CSS 2 and CSS 3, and JavaScript 1.6.
  • Improved pop-up blocking
  • Faster browser navigation with improvements to back and forward button performance.
  • Drag and drop reordering for browser tabs.

VirtualHosts little bit more…

You can make a domain run on a different port than 80, which is the default port of HTTP, in the previous examples of VirtualHost Configurations, I’ven’t specified the port, which implicitly is 80.

If you want to run the website on a different port, you need to make sure Apache is listning on that port. To do that, you set a directive Listen

Listen 8080

Alternatively you can also specify the IP on which it should listen.

Listen 67.66.65.64:8080

Now if you want to run a Name-based VirtualHost on a specific, you make sure that you set the NameVirtualHost directive to a specific port as well.

NameVirtualHost 67.66.65.64:8080

Once you’ve set the NameVirtualHost, you need to set the actual VirtualHost configuration as well.
there is just once change to be made…

<VirtualHost 67.66.65.64:8080>
...
</VirtualHost>>

Important: You should note that all the domains, ruturaj.net, www.ruturaj.net, yourname.com, should always resolve an IP address on which NameVirtualHost is defined. Without which, the configuration does not make any sense.

Setting VirtualHosts

VirtualHosts
The most important part of setting Apache is setting the hosts, or VirtualHosts. The term “VirtualHost” comes from the fact that one single host or comptuer is hosting many hostnames. Apache was the one to start of with this type of hosting, in this Apache picks up the Host header from a standard HTTP request to translate the website associated for that host. This type of hosting is known as the Name-based virtual hosting, which is the most common of all the hosting types. The other one is the IP-based hosting which requires each domain to have a separate IP.

What I will show you is how to set up a name based virtualhost.

Now, A simple GET request for my page root would be as

GET / HTTP/1.1
Host: www.ruturaj.net

Now apache picks up “www.ruturaj.net” from the request header and then translates it to the virtual host that is mapped to www.ruturaj.net

Lets assume you have an IP 67.66.65.64, that you need to set up for virtual hosting, then first, you need to tell Apache that this IP is used for Namebased Virtual hosting.

NameVirtualHost 67.66.65.64

Now that you have done with setting the IP for virtual hosting, you need to configure the VirtualHosts.

Let us take ruturaj.net as the domain that needs to be set. So here it goes

<VirtualHost 67.66.65.64>
  ServerName ruturaj.net
  ServerAlias www.ruturaj.net
  DocumentRoot /www/domains/ruturaj.net
  CustomLog logs/ruturaj.net-access_log combined
  ErrorLog logs/ruturaj.net-error_log
  DirectoryIndex index.php
  ServerAdmin ruturaj@ruturaj.net
</VirtualHost>

Now let us review the configurations

  • ServerName: this is the main servername, it should be domain name
  • ServerAlias: this is an alias, eg www.ruturaj.net should mean same as ruturaj.net on HTTP
    You can set anything like default.ruturaj.net as well. Just make sure that default.ruturaj.net points to 67.66.65.64
  • DocumentRoot: This is the main directory that points to ruturaj.net domain, this is the file system path to the directory
  • CustomLog: This is the access_log for ruturaj.net, remember, we’d set the variable of “combined” log format, we are useing it here, if you want a different format, you can specify the LogFormat before specifying the CustomLog directive
  • ErrorLog: Any errors while serving are logged in this file
  • DirectoryIndex: Defines the default document page for root, eg when you do http://ruturaj.net/ it tells the server to serve “index.php”, so you can set it whatever you want default-page.html, default.pl, etc.
  • ServerAdmin: Just specify the email address, this would show up, when there is any server error.

So now if you want to add a configuration for host “johnsmith.com”…

<VirtualHost 67.66.65.64>
  ServerName johnsmith.com
  ServerAlias www.johnsmith.com
  DocumentRoot /www/domains/johnsmith.com
  CustomLog logs/johnsmith.com-access_log combined
  ErrorLog logs/johnsmith.com-error_log
  DirectoryIndex index.php
  ServerAdmin admin@johnsmith.com
</VirtualHost>