Multi-player Ajax Games

Today I came across an interesting article about creating multi-player video games using Ajax. The article mainly deals with how you would send data to and from the server and also touches on keeping the game in sync on multiple clients.

The below code is how the post purposes that you would send data to the server side (this code uses a hand rolled Ajax call, but you could change it to use a library).

var httpSend = null;
var httpGet = null;

function send(action)
{
httpSend=GetXmlHttpObject();
if (httpSend==null){alert (?Your browser does not support AJAX!?);return;}

var url=?send.php?;
url=url+??action=?+action;
url=url+?&p=?+player;
url=url+?&g=?+gameid;
url=url+?&sid=?+Math.random();
httpSend.onreadystatechange=stateSend;
httpSend.open(?GET?,url,true);
httpSend.send(null);
}

function get()
{
if(httpGet != null) { return 0; }

httpGet=GetXmlHttpObject();
if (httpGet==null){alert (?Your browser does not support AJAX!?);return;}

var url=?get.php?;
url=url+??sid=?+Math.random();
url=url+?&p=?+player;
url=url+?&g=?+gameid;
httpGet.onreadystatechange=stateGet;
httpGet.open(?GET?,url,true);

httpGet.send(null);
}

function stateSend() {
if (httpSend.readyState==4){}
}

function stateGet() {
if (httpGet.readyState==4)
{
str = httpGet.responseText;
if(str != ?){
eval(str);
}
httpGet = null;
}
}

function GetXmlHttpObject() {
var xmlHttp=null;
try {
xmlHttp=new XMLHttpRequest();
}
catch (e) {
try {
xmlHttp=new ActiveXObject(?Msxml2.XMLHTTP?);
}
catch (e) {
xmlHttp=new ActiveXObject(?Microsoft.XMLHTTP?);
}
}
return xmlHttp;
}

The following code would be on the server side to receive messages. In the case of this example the code is PHP and the file is called Get.php

<?php
include(?config.php?);
$p = $_GET[?p’];
$g = $_GET[?g’];
$action = ?;
$query = mysql_query(?SELECT * FROM actions WHERE id = ?.$g);
$row = mysql_fetch_array($query);
$action = $row[$p];
$action = stripslashes($action);
$str = ?update actions set `?.$p.?` = ? where id = ?.$g;
mysql_query($str);
echo $action;
?>

The following code would be on the server side to send messages. In the case of this example the code is PHP and the file is called Send.php

<?php
include(?config.php?);
$p = $_GET[?p’];
$g = $_GET[?g’];
if($p == 1)
{
$b = 2;
}
elseif($p == 2)
{
$b = 1;
}
$action = $_GET[?action?];
$action = addslashes($action);
$query1 = mysql_query(?select * from actions where id = ?.$g);
$row = mysql_fetch_array($query1);
$str = $row[$b];
$str = $str . $action;
$str = ?UPDATE actions SET `?.$b.?` = ??.$str.?? where id = ?.$g;
$query = mysql_query($str);
if(!$query)
{
echo mysql_error().$str;
}
else
{
echo 0;
}
?>

You can read the full post here

The post also touches on the possibility of sending data via a text string. I personally think that for multi-player games JSON is a perfect data transfer method. Unlike XML there is not a large overhead and unlike sending data via a text string there is no parsing needed on the client which should help performance. This post is interesting as I think that Ajax can be a very useful method of transferring data for multi-player games.

Easy Server Side Caching in PHP

Tagged:  

When developing dynamic web applications there may be many times that data is not updated for a certain amount of time. In PHP it is fairly simple to have a page cached, so that there is not much load on the server.

To create this caching you would put some code like the following on the top of your PHP page.

$cachefile = 'caching_folder/cachedpage.html';
$cachetime = 30;
// Serve from the cache if it is younger than $cachetime
if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) {
    include($cachefile);
    exit;
}
ob_start(); // Start the output buffer

The things that you would change in the above code is the setting of the $cachfile variable to the name of the static file that the cache will be saving on the server (you will need to set permissions on the folder where you want to save the cached file). You will also want to change the $cachetime variable to the number of seconds between each caching.

Now you would put all of your standard PHP code to create the page after the above code. Once you have all of your standard PHP code you would put the below code to actually save the cache file.

// Cache the output to a file
$fp = fopen($cachefile, 'w');
fwrite($fp, ob_get_contents());
fclose($fp);
ob_end_flush(); // Send the output to the browser

This script is very handy and a version of it is used in the del.icio.us Spy application to avoid too many calls to the del.icio.us servers.

PostgreSQL 8.3 - Finally Released!

Tagged:  

After much waiting ProstgreSQL 8.3 has been released. This is a much better performing release from version 8.2. You can find some benchmarks that I wrote about previously here.

Below is an excerpt from the press release:

4 February 2008, New York, NY: The PostgreSQL Global Development Group today announced the release of version 8.3 of the high-performance object-relational database management system. This release includes a record number of new and improved features which will greatly enhance PostgreSQL for application designers, database administrators, and users, with more than 280 patches by dozens of PostgreSQL contributors from 18 countries.

"The continued evolution of the open source PostgreSQL database gives users the option of deploying a non-proprietary database, allowing them to save money, improve performance and increase productivity. PostgreSQL 8.3 is an impressive new release and we encourage customers around the world to explore it," said Rich Green, executive vice president of software at Sun Microsystems.

Version 8.3 provides greater consistency of performance than previous versions, ensuring that every user can depend on the same high performance demonstrated in recent benchmarks for every transaction, whether in peak hours or not, seven days a week, 52 weeks per year. Major performance enhancements include:

* Heap Only Tuples (HOT), which eliminate up to 3/4 of the maintenance overhead of frequently updated tables
* Spread checkpoints and background writer autotuning, which reduce the impact of checkpoints on response times
* Asynchronous commit option for much faster response times on some transactions

These changes also significantly accelerate transaction processing throughput, between 5% and 30%, depending on the workload.

"PostgreSQL just got smarter," said Bruce Momjian, PostgreSQL Core Team member.

PostgreSQL is the first open source database to implement Synchronized Scan, which greatly reduces I/O for data mining. The Windows team has enabled Visual C++ compilation of PostgreSQL, improving stability and performance on Windows, as well as accessibility to the project to Windows contributors. New logging options have been added and the overhead of the statistics collector has been diminished in order to make it easier to monitor your servers.

Of course, this wouldn't be a proper PostgreSQL release without providing lots of new features for application developers, including:

  • ANSI-standard SQL/XML support, including XML export
  • Text search: our advanced full text search tool, TSearch2, has been merged into the core distribution with better management and new dictionaries and languages
  • GSSAPI and SSPI authentication support
  • New data types: UUIDs, ENUMs and arrays of composite types

"We process over 18,000 queries per second on over 300GB of user data on our PostgreSQL servers, and those numbers go up every month," said Gavin Roy, CTO of social networking site MyYearbook.com. "We're very excited about HOT, shared buffer scan improvements and integrated tsearch indexing. Preliminary testing shows that 8.3 will improve our database load profile while decreasing response times. We're really looking forward to it."

In addition to the many new core features, several new optional components have matured and released 1.0 versions during the 8.3 release cycle. These include SNMP support, horizontal scalability options such as PL/Proxy, pgPool-II, and Bucardo, a graphical debugger for stored procedures, and a scalable connection pooler called pgBouncer. These add to the rich set of accessories already available.

You can read the full release here.

If you are using PostgreSQL 8.2, I definetly recommend upgrading to version 8.3.

You can download the version 8.3 here.

del.icio.us Spy - New Features

Tagged:  

Ajaxonomy's del.icio.us Spy has received quite a positive response around the blogosphere, however, there is always room for improvement. So, having read some comments from people we have decided to make some of the improvements that where in these comments.

The improvements and new features can be found below:

Improved Filtering: The previous version filtered links based on the title of links. The new version filters links based on the links del.icio.us tags.

Submitter User Id: The new version displays the user id of the submitter of the link. This allows for users to view other links from users that they think provide interesting links.

Save For Later: The application now has a Save For Later feature which puts the links that the user thinks are interesting into a temporary holder, so he can go back later and investigate the link. If they like the link they can permanently save it using del.icio.us or another social site.

We hope that you continue to find the del.icio.us Spy useful and would love to hear any additional feedback that you have.

You can get to the application from the Ajaxonomy Labs section of this site (on the right side bar) or you can go to the application here.

IncludeJS - include and compress JavaScript easily

Justin Meyer has been working on a JavaScript library named IncludeJS and has released a 0.1 alpha 1 Developer package. IncludeJS lets developers include and compress JavaScript files easily. The hope for the library is "to bridge the gap between frameworks like jQuery/Prototype which guess at what you will most likely need, and frameworks like MooTools, which are great if you know exactly what you want and don't need to look in the source."

IncludeJS was originally a component of JavaScriptMVC - an open source JavaScript Model-View-Controller framework. The framework is going through some major changes and individual components are being extracted to make each individually useful.

Features of IncludeJS:

Relative paths.

Instead of including files relative to the current page's url,
IncludeJS includes files relative to your JavaScript files' urls.
Forget about scanning the page's script tags for your library's path.
IncludeJS lets you organize your scripts however you want.

Dynamic compression.

IncludeJS uses Dean Edwards packer
to automatically compress your
JavaScripts. Unlike server-side compression scripts,
compression is determined at runtime. This makes
it easy to compress large libraries with optional plugins.

Highlights.

- Consistant include order (last-in-first-out)
- FF 1.5+, IE 6+, Opera 9, Safari 3.
- Works with libraries like Prototype and jQuery.
- MIT license.
- 3 KB compressed.
- Files visible in Firebug.

Usage

1) Include the library in your page

<script src="include.js" type="text/javascript">
</script>

2) Include JavaScript files with the include function, files are relative to the including file and will be included in LIFO [last-in-first-out] order.

<script type="text/javascript">
   include( 'javascripts/prototype',
            'javascripts/myapplication'
   )
</script>

3) Compress your app by adding the line:

include.setup('compress')

before your includes, after the page loads you're presented with a compressed version of the code.

<script type="text/javascript">
   include.setup('compress')
   include( 'javascripts/prototype',
            'javascripts/myapplication'

   )
</script>

4) Run it! After you've saved the compressed version of the code, change the "compress" argument to "production" and specify the path to the newly created library as a second argument.

<script type="text/javascript">
   include.setup('production','path/to/prod')
   include( 'javascripts/prototype',
            'javascripts/myapplication'
   )

</script>

Visit the IncludeJS Homepage

Check out the demo over at JavaScriptMVC.com

More JavaScript/Ajax Cheatsheets

Tagged:  

Scott Klarr has posted a collection of some JavaScript/Ajax cheatsheets on his blog.

The cheatsheets include:

  • Javascript Cheat Sheets
  • jQuery Cheat Sheets
  • Scriptaculous Cheat Sheets
  • Prototype Cheat Sheets
  • Microsoft Ajax Library Cheat Sheets
  • Yahoo YUI Cheat Sheets
  • ...and more...
  • Click here to read the post and to download the cheatsheets.

Easy No Table Design Using the YUI CSS Grid Builder

Tagged:  

In designing a web page most of us know that it is better to stay away from using tables in our design and instead use full CSS. This is great in theory, but in practice it can be quite a bit more complicated.

Well, Yahoo! has felt our pain and has built a visual tool to make page layout much easier. The tool is the Yahoo! User Interface CSS Grid Builder.

The tool is very easy to use, you simply click the various option to create the page layout that you would like. Once you have the page how you would like it, you simply click on the "Show Code" button and then copy and paste the code. Now you can start scripting and adding content to your page.

If you aren't already using this tool you should at least check it out (click here to go to the application).

Microsoft + Yahoo! = Micrahoo!?

Tagged:  

I'm sure that you have already heard about the possibility of Microsoft buying Yahoo!. I'm not going to go in to much detail about deal, as I'm sure that you've already had your fill of that. Instead, I want to take a brief look into how this may affect Yahoo! in the future.

If Microsoft does in fact buy Yahoo!, it is very possible that all new development will be using Microsoft technologies instead of the current technologies. When I heard of this deal, the first thing I thought was that all the future development will be done in .NET technologies and run on Windows servers (can you say "nightly reboot"?).

From a web developers perspective, I really like the work that Yahoo! has done with the Yahoo! User Interface toolkit, but if Microsoft buys Yahoo!, will development stop as Microsoft tries to push Silverlight? Not to mention the possibility of abandoning JSON as Microsoft seems to prefer XML for Ajax applications.

I personally look at this with the worry that Yahoo! will stop being an innovator, as Microsoft looks to compete with Google and push their own technologies.

I would love to hear your thoughts on this, you can leave a comment or write a blog post with your free account on this site (once you login click on "Create content" => "Blog entry").

Debugging PHP

Tagged:  

Even though I really enjoy developing in PHP there are times that debugging an issue can be very frustrating. I found a good tutorial on debugging PHP.

Below is an excerpt from the tutorial.

Starting with the Basics - Parse Errors

Parse errors can be one of the most irritating bugs for new PHP programmers to solve. A missing quote ("), bracket ({,}), and a multitude of other errors can be thrown by the interpreter which may leave you asking "What is wrong?".

Consider this code:

PHP Code:


<?php

print "Hello World;

?>


You may notice the missing " after World and before ;. When this code is ran it casts the error:

Code:
Parse error: syntax error, unexpected $end in C:\wamp\www\broken.php on line 5

Which may leaving you asking, what is wrong with line 5?

Line 5:

PHP Code:



?> 



The line numbers may be a little deceiving at first, causing a new PHP programmer to overlook the problem. The real issue is caused because the interpreter sees a quote before Hello and assumes a string will follow. With no ending quote, the interpreter reaches the end of the script, but never completes the string assignment.

When such an error is cast, take a look at the actual line first. In this case: ?>. If no immediate errors appear start working your way backwards line-by-line. Do a quick scan of each line making sure you have terminated them correct (;). Make sure matching pairs have an ending pair (in this case the quote).

Examples of matching pairs:
[ ]
{ }
" "
' '

Now consider the following code:

PHP Code:



<?php
$yourName 
"Jordan";

if $yourName == "Jordan")
{
  echo 
"Hello $yourName";
}
?>



At a closer look, you see that line 4 is missing the opening (. When this code is ran the interpreter will produce the following error:

Code:
Parse error: syntax error, unexpected T_VARIABLE, expecting '(' in C:\wamp\www\broken.php on line 4

Notice this error message correctly states the line number where the error occurred which is why it is very important to start on the line number given and work backwards. What actually happened was the interpreter read the "if" keyword and expected an open parenthesis followed by a condition. Instead it read "$yourName", a T_VARIABLE or token. What this message translates into is "While on line 4, I was expecting a '(' but received a variable."

You can view the full tutorial here.

I hope this helps you when you run into an issue coding PHP.

As always, if you find anything cool you can blog about it on this site with your free account (Once logged in click on "Create content" => "Blog entry" and then blog away).

Making the Most of Java 5: Exploring Generics

Tagged:  

Erasure aside, the addition of generics to Java (see intro here) brings added dimension to using types in the language. The most obvious application of generics is the ability to declare homogeneous Collection types, such as Collection<String>, but there are less obvious ones as well. I'll explore some of these in this article.

Type Inference

But first, a little diversion. Generics can be used both at the class level and at the method level in Java. Let's suppose we have a generic method like so:

public <T> T getSomething() { ... }

What happens if we do an assignment to a String?

String s = getSomething();

It compiles just fine. The same is true of the following:

Integer i = getSomething();

What is going on here? As you may have guessed, generic methods have an ability to do type inference, that is, they are able to figure out the type from the context of its use in an assignment expression. Quite a new wrinkle for an explicitly-typed language like Java.

If you define a generic type for a parameter to the method getSomething() that also uses <T>, the type defined by the parameter takes "precedence" over assignment inference.

Type-Inferred Factory Method

As Joshua Bloch pointed out in his "Effective Java Reloaded" presentation at JavaOne 2007, you can use this type inference to simplify the creation of complex generic types using a static factory method. Adding a method to the java.util.HashMap class like

public static <K,V> HashMap<K,V> newInstance() {
     return new HashMap<K,V>();
}

simplifies the creation of a complex HashMap object from

Map<String,List<Integer>> map = new HashMap<String,List<Integer>>();

to a much easier-to-read form like

Map<String,List<Integer>> map = HashMap.newInstance();

Type inference makes this possible.

Type-Safe Factory Method

Often factory methods will have a very general applicability, and so in earlier versions of Java, were forced to return an Object which was expected to be cast to the correct type. A good example of this is the java.lang.reflect.Proxy class which has the method:

public static Object newProxyInstance(ClassLoader loader,
     Class<?>[] interfaces,
     InvocationHandler h) 

Assuming that we only want to use the current ClassLoader and we are proxying using only a single interface, we can genericize this method to the following:

public static <T> T newProxyInstance(Class<T> interface, 
     InvocationHandler h)

(One could also genericize the InvocationHandler class with the generic type <T>, as well, so that the first argument of its invoke method was the correct type). Here interface argument is also functioning as a "type token", providing a guarantee that the factory method will return an instance of the correct type and the implementer with the means to do so (via the cast()). Since the type of the Class parameter passed in determines the type of <T>, it acts as a kind of "hook" to determine the type of the return value. Thus this method will not need to have its return value explicitly cast, and will never throw a ClassCastException.

Another great example of this technique are the various bind() methods for the Binder class in the Google Guice library. The type passed into the bind() method is "hooked" via a generic type to the type passed into the various chained to(), toProvider(), toInstance(), and annotatedWith() methods. Hence a "line of configuration" in a Google Guice Module that would define the dependency injection for a Collection interface would look like:

binder.bind(Collection.class).to(ArrayList.class);

Thanks to the use of a generic type, the parameter to the method to() is guaranteed to be of an assignable type to that of the method bind().

Guarantee of Behavior

A little-known part of the Generics specification is the ability to define conjunctive types, that is, multiple types separated by an '&' operator, when defining a generic bounded type. You can use this to make sure that a parameter to a method implements specific interfaces. For example, let's say that you have a method that takes an implementation of a certain interface MyInterface.

public void doSomething(MyInterface onObject) { ... }

Let's also say that you want the passed-in parameter to also implement java.lang.Comparable and java.io.Serializable so that you could sort and serialize the parameter in the method. How would you do this? Well, you could put guard code in your method and throw an IllegalArgumentException--and document this well--but compile-time errors are much preferable to runtime ones. This is where conjunctive generic types come to the rescue...you can change this method to the following:

public <T extends MyInterface & Comparable<T> & Serializable> 
     void doSomething(T onObject)

Now the caller of the method will get a compile error if they try to pass in an implementation of MyInterface that does not also implement the other two interfaces.

Conclusion

Despite some annoyances to the generics implementation in Java (read: erasure), Generics do bring an extra layer to the type safety of the language that can be used in new and creative ways. Once you get past the gotchas, they make your Java programs safer.

Syndicate content