Webessence

Server Sent Events

Server Sent Events (SSE) can be used to get "push" notifications from the server. It is really a standardized way of polling the server for new notifications (COMET). The client uses the EventSource object for this. This object makes a request to the URL and when it receives data, it fires events.

var source = new EventSource("http://www.mysite.com/updates.php");
source.addEventListener("message", function(e) {
console.log(e.data);
}, false);

The server should not closes the connection, but keeps it open. When the connection is closed, the client will automatically reconnect. The server can send a "retry" command with the number of milliseconds that the client should wait to reconnect. Because the webserver should not closes the connection, Apache is not really suitable for this. Servers like node.js are better, because of the event loop.

Some good links:

Javascript | 2012-02-18 18:52:57 | Comments (0)

WebSQL

Interesting links

At this point, WebSQL is supported by Safari, Chrome and Opera. Chrome also supports IndexedDB, but Safari doesn't, so this means if you develop for mobile or tablet, WebSQL cannot be ignored. The W3 has deprecated WebSQL in favour of IndexedDB, which has something strange in it, because the 2 storage engines don't have the same functionality.

The benefits of using WebSQL in relation to webstorage:

  • The data are more structured.
  • Relational.
  • Transactions.
  • You can request more space.

The benefits of using WebSQL in relation to IndexedDB:

  • You can do full text search (like the LIKE query) - this is not possible with IndexedDB.
  • For many developers, it makes use of good old SQL (IndexedDB is a NoSQL database).

The API in short

Put simply, the steps you need to do are:

  1. Open or create a database.
  2. Create a transaction.
  3. Execute queries inside this transaction.

Read more...

Javascript | 2012-02-05 09:30:50 | Comments (0)

Using the Application Cache

The application cache (appcache) makes it possible to run a website offline. It makes use of a manifest file with entries of files inside it. When an appcache exists, every call to the files inside it are served directly from this appcache - no network access is done and needed.

When a manifest attribute is encountered and the appcache does not already exists, the browsers creates a new appcache and downloads all entries inside this manifest file and adds these to the appcahe. This happens in the background. With event listeners you can see what's happening.

Read more...

Javascript | 2012-02-04 13:20:30 | Comments (0)

Dynamically add javascript files

There are some caveats when dynamically adding SCRIPT tags. To know when the added script has been downloaded, you can use the following function. It makes use of the load event when available with a fallback to the readystatechange event. The callback has access to the SCRIPT tag (this) and the event object.

function includeScript(src, callback) {
var script = document.createElement("script");
// IE will download the script as soon as the attribute src is set.
script.setAttribute("src", src);

if (typeof script.onload !== "undefined") {
// Chrome, Firefox and IE9
script.onload = callback;
} else if (typeof script.readyState !== "undefined") {
// IE < 9
script.onreadystatechange = function() {
if (script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null;
callback.call(script, window.event);
}
};
}

document.getElementsByTagName("head")[0].appendChild(script);
}

// this = SCRIPT element.
// e = event object.
function scriptLoaded(e) {
alert("I downloaded " + this.src + " and the event was: " + e.type);
}

To add a script and execute some code after the script has been downloaded:

includeScript("test.js", scriptLoaded);

As in the article http://www.blaze.io/technical/ies-premature-execution-problem/ is explained, always add the created SCRIPT element to an element that is already attached to the DOM (like the HEAD element).

Javascript | 2011-12-27 12:30:22 | Comments (0)

MySQL to CSV

With mysqldump you can only create a CSV file if you have permission (and access) to the database server filesystem. So if you have a remote database server, you can use the following:

mysql -u[username] -h[server] -p[password] -B
-e "select * from database.table"
--default-character-set=utf8 > dump.csv
MySQL | 2011-12-16 12:24:12 | Comments (0)

Asynchronous execute script in PHP without fork

The usage of pcntl_fork in a webserver environment is not encouraged according the PHP documentation. As an alternative, you can use the following code:

exec("/usr/bin/php some_script.php > /dev/null &");
// Here you can do some more actions, while some_script.php
// is still executing.

Even if the caller script has ended, the some_script.php will still run. A drawback certainly is the lack of return value.

PHP | 2011-12-07 15:41:37 | Comments (1)

Practical self defining or lazy function definiton

In Javascript Patterns by Stoyan Stefanov I read about self defining functions (also called lazy function definition). Last day I was writing an event handler for the mousemove event. For Firefox, Chrome and IE9 I could use the pageX and pageY properties of the event object. Off course, in IE < 8 this did not work, so I had to use e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft. I didn't want to test for this property everytime in the mousemove event handler, for performance reasons. After some time, I realised I had created a self defining function:

var getPageXY = function(e) {
if ("pageX" in e) {
getPageXY = function(e) {
return {"x" : e.pageX, "y" : e.pageY}
};
return getPageXY(e);
} else {
getPageXY = function(e) {
return {
"x" : e.clientX + doc.body.scrollLeft + doc.documentElement.scrollLeft,
"y" : e.clientY + doc.body.scrollTop + doc.documentElement.scrollTop};
};
return getPageXY(e);
}
};

So the first time this function is called (in a mousemove event handler), this function rewrites itself, so the next time it is called, it just does what is has to do.

Javascript | 2011-11-26 20:23:07 | Comments (0)

Javascript templating

A slightly modified version of John Resigs brilliant script JavaScript Micro-Templating. The modifications are:

  • Replace most of the regular expressions by splits, so it is easier to understand (at least for me) and it looks to be just as fast as the original.
  • I added an AJAX handler, so you can have external templates compiled on the fly.
  • Some refactoring, like the cache and the way it gets the template (by ID or by AJAX).

Read more...

Javascript | 2011-11-19 10:32:43 | Comments (2)

MySQL safe-updates for dummies

I just executed an update without the WHERE clause, so I guess I'm still a dummy...

So the next time, I will connect with:

mysql -uusername -p --safe-updates

Or:

mysql -uusername -p --i-am-a-dummy
MySQL | 2011-11-17 14:23:12 | Comments (2)

MySQL GET_LOCK

An easy way to prevent overlapping of cron jobs, is using the GET_LOCK function from MySQL. This function has the following definition:

GET_LOCK(name_of_lock, timeout)

It tries to get the named lock name_of_lock for timeout seconds. It returns 1 when it gets the lock, 0 if it timed out and NULL when an error occurred. The lock gets released when you call RELEASE_LOCK, closes the connection or call another GET_LOCK (!). This lock is server wide. This means that any code that connects to the same database server and asks for the same lock, has to wait until you have released it.

A PHP example:

$lock = 0;
// The variable $con is a MySQL connection.
// Try to get the lock for 10 seconds.
$query = "SELECT GET_LOCK('my_lock', 10)";
if (($result = $con->query($query))) {
if (($row = $result->fetch_row())) {
$lock = $row[0];
}
}

if ($lock == 0) {
die("Can't get the lock.");
}

// Here we can do our thing.
// If a job is here, and another job is started, it will not get the lock.

// Here we release the lock.
$con->close();
MySQL, PHP | 2011-11-17 14:14:46 | Comments (0)