Web Sockets

Real-time interaction has been something web developers have been trying to do for many years, but most of the implementations have involved using JavaScript to periodically hit the remote server to check for changes. HTTP is a stateless protocol, so a web browser makes a connection to a server, gets a response, and disconnects. Doing any kind of real-time work over a stateless protocol can be quite rough. The HTML5 specification introduced Web Sockets, which let the browser make a stateful connection to a remote server.7 We can use Web Sockets to build all kinds of great applications. One of the best ways to get a feel for how Web Sockets work is to write a chat client, which, coincidentally, AwesomeCo wants for its support site.

AwesomeCo wants to create a simple web-based chat interface on its support site that will let members of the support staff communicate internally, because the support staff is located in different cities. We’ll use Web Sockets to implement the web interface for the chat server.
Users can connect and send a message to the server. Every connected user will see the message. Our visitors can assign themselves a nickname by sending a message such as “/nick brian,” mimicking the IRC chat protocol. We won’t be writing the actual server for this, because that has thankfully already been written by another developer.

The Chat Interface

We’re looking to build a very simple chat interface that looks like Figure 10.2, on the next page, with a form to change the user’s nickname, a large area where the messages will appear, and, finally, a form to post a message to the chat.

In a new HTML5 page, we’ll add the markup for the chat interface, which consists of two forms and a div that will contain the chat messages.

<div id=”chat_wrapper”>
<h2>AwesomeCo Help!</h2>
<form id=”nick_form” action=”#” method=”post” accept-charset=”utf-8″>
<p>
<label>Ni ckname
<input id=”nickname” type=”text” value=”Guestl)ser”/>
</label>
<input type=”submit” value=”Change”>
</p>
</form>
<div id=”chat”>connecting….</div>
<form id=”chat_form” action=”#” method=”post” accept-charset=”utf-8″>
<p>
<label>Message
<input id=”message” type=”text” />
</label>
<input type=”submit” value=”Send”>
</p>
</form>
< / d i v >

We’ll also need to add links to a style sheet and a JavaScript file that will contain our code to communicate with our Web Sockets server.

<script src=’chat.js’ type=’text/javascript’></script>
<link rel=”stylesheet” href=”style.css” media=”screen”>

Our style sheet contains these style definitions:

Une l #chat_wrapper{
w i d t h : 320px;
h e i g h t : 440px;
b a c k g r o u n d – c o l o r : #ddd;
5 padding: lOpx;
}
#chat_wrapper h2{
m a r g i n : 0;
}
# c h a t {
w i d t h : 300px;
h e i g h t : 300px;
o v e r f l o w : auto;
15 background-color: #fff;
p a d d i n g : lOpx;
}

On line 14, we set the overflow property on the chat message area so that its height is fixed and any text that doesn’t fit should be hidden, viewable with scrollbars.

With our interface in place, we can get to work on the JavaScript that will make it talk with our chat server.

Talking to the Server

No matter what Web Sockets server we’re working with, we’ll use the same pattern over and over. We’ll make a connection to the server, and then we’ll listen for events from the server and respond appropriately.

EventIn our chat.js file, we first need to connect to our Web Sockets server, like this:

v a r webSocket = new W e b S o c k e t ( ‘ w s : / / l o c a l h o s t : 9 3 9 4 / ‘ ) ;

When we connect to the server, we should let the user know. We define the onopen() method like this:

webSocket.onopen = f u n c t i o n ( e v e n t ) {
$ ( ‘ # c h a t ‘ ) . a p p e n d ( ‘ < b r > C o n n e c t e d to the s e r v e r ‘ ) ;
};

When the browser opens the connection to the server, we put a message in the chat window. Next, we need to display the messages sent to the chat server. We do that by defining the onmessage() method like this:

webSocket.onmessage = f u n c t i o n ( e v e n t ) {
$ ( ‘ # c h a t ‘ ) . a p p e n d ( ” < b r > ” + e v e n t . d a t a ) ;
$ ( ‘ # c h a t ‘ ) . a n i m a t e ( { s c r o l l T o p : $ ( ‘ # c h a t ‘ ) . h e i g h t O } ) ;

The message comes back to us via the event object’s data property. We just add it to our chat window. We’ll prepend a break so each response falls on its own line, but you could mark this up any way you wanted.

Next we’ll handle disconnections. The onclose() method fires whenever the connection is closed.

w e b S o c k e t . o n c l o s e = f u n c t i o n ( e v e n t ) {
$ ( ” # c h a t ” ) . a p p e n d ( ‘ < b r > C o n n e c t i o n c l o s e d ‘ ) ;
};
};

Now we just need to hook up the text area for the chat form so we can send our messages to the chat server.

$ ( f u n c t i o n ( ) {
$( “form#chat_form”) . submi t ( f u n c t i o n ( e ) {
e . p r e v e n t D e f a u l t ( ) ;
v a r t e x t f i e l d = $(“#message”) ;
w e b S o c k e t . s e n d ( t e x t f i e l d . v a l ( ) ) ;
t e x t f i e l d . v a l ( ” ” ) ;
} ) ;

We hook into the form submit event, grab the value of the form field, and send it to the chat server using the send() method.

We implement the nickname-changing feature the same way, except we prefix the message we’re sending with “/nick.” The chat server will see that and change the user’s name.

$( “form#nick_form”) . submi t ( f u n c t i o n ( e ) {
e . p r e v e n t D e f a u l t ( ) ;
var t e x t f i e l d = $(“#m’c/cname”) ;
webSocket.send(“/m’c/c ” + t e x t f i e l d . v a l ( ) ) ;
} ) ;

That’s all there is to it. Safari 5 and Chrome 5 users can immediately participate in real-time chats using this client. Of course, we still need to support browsers without native Web  Sockets support. We’ll do that using Flash.

Falling Back

Browsers may not all have support for making socket connections, but Adobe Flash has had it for quite some time. We can use Flash to act as our socket communication layer, and thanks to the web-socket-js9 library, implementing a Flash fallback is a piece of cake.

We can download a copy of the plug-in10 and place it within our project. We then need to include the three JavaScript files on our page:

<script type=”text/javascript” src=”websocket_js/swfobject.js”x/script>
<script type=”text/javascript” src=”websocket_js/FABridge.js”x/script>
<script type=”text/javascript” src=”websocket_js/web_socket.js”x/script>
<script src=’chat.js’ type=’text/javascript’></script>
<link rel=”stylesheet” href=”style.css” media=”screen”>
</head>
<body>
<div id=”chat_wrapper”>
<h2>AwesomeCo Help!</h2>
<form id=”nick_form” action=”#” method=”post” accept-charset=”utf-8″>
<p>
<label>Ni ckname
<input id=”nickname” type=”text” value=”Guestl)ser”/>
</label>

<input type=”submit” value=”Change”>
</p>
</form>
<div id=”chat”>connecting….</div>
<form id=”chat_form” action=”#” method=”post” accept-charset=”utf-8″>
<p>
<label>Message
<input id=”message” type=”text” />
</label>
<input type=”submit” value=”Send”>
</p>
</form>
< / d i v >
</body>
</html>

The only change we need to make to our chat.js file Is to set a variable that specifies the location of the WebSocketMain file.

WEB_SOCKET_SWF_|_OCATION “websocket_js/WebSocketMain. swf” ;

With that In place, our chat application will work on all major browsers, provided that the server hosting your chat server also serves a Flash Socket Policy file.

Flash Socket Policy What?

For security purposes, Flash Player will only communicate via sockets with servers that allow connections to Flash Player. Flash Player attempts to retrieve a Flash Socket Policy file first on port 843 and then on the same port your server uses. It will expect the server to return a
response like this:

<cross-domain-policy>
<allow-access-from domain=”*” to-ports=”*” />
</cross-domain-policy>

This Is a very generic policy file that allows everyone to connect to this service. You’d want to specify the policy to be more restrictive if you were working with more sensitive data. Just remember that you have to serve this file from the same server that’s serving your Web Sockets server, on either the same port or the port 843.

The example code for this section contains a simple Flash Socket Policy server written in Ruby that you can use for testing. See Section 25,

Servers, for more on how to set that up on your own environment for testing.

Chat servers are just the beginning. With Web Sockets, we now have a robust and simple way to push data to our visitors’ browsers.

Servers

The book’s source code distribution contains a version of the Web Sockets server we’re targeting. It’s written in Ruby, so you’ll need a Ruby interpreter. For instructions on getting Ruby working on your system, see the file RUBY_README.txt within the book’s source code files.

You can start it up by navigating to its containing folder and typing this:

ruby s e r v e r . r b

In addition to the chat server, there are two other servers you may want to use while testing the examples in this chapter. The first server, client.rb, serves the chat interface and JavaScript files. The other server, flashpolicyserver, serves a Flash Policy file that our Flash-based Web Sockets fallback code will need to contact in order to connect to the
actual chat server. Flash Player uses these policy files to determine whether it is allowed to talk to a remote domain.

If you’re running on a Mac or a Linux-based operating system, you can start all these servers at once with this:

rake s t a r t

from the html5_websockets folder.

 

 

Playing Nicely with Other APIs

Many interesting APIs that started out as part of the HTML5 specification were eventually spun off into their own projects. Others have become so associated with HTML5 that sometimes it’s hard for developers (and even authors) to really tell the difference. In this chapter, we’ll talk about those APIs. We’ll spend a little time working with the HTML5 history API, and then we’ll make pages on different servers talk with Cross-document Messaging, Then we’ll look at Web Sockets and Geolocation, two very powerful APIs that can help you make even more interactive applications.

We’ll use the following APIs to build those applications:

History
Manages the browser history. [C5, S4, IE8, F3, OlO.l IOS3.2, A2]
Cross-document Messaging
Sends messages between windows with content loaded on different
domains. [C5, S5, F4, IOS4.1, A2]
Web Sockets
Creates a stateful connection between a browser and a server. [C5,S5, F4, IOS4.2]
Geolocation
Gets latitude and longitude from the client’s browser. [C5, S5,F3.5, 010.6, IOS3.2, A2]

 

Working with Client-Side Data

We have talked about HTML5 and CSS3 markup, but now let’s turn our attention to some of  the technologies and features associated with HTML5. Cross-document Messaging and  offline support, for example, let us communicate across domains and create solutions that let  our users work offline.

Some features such as Web Storage, Web SQL Databases, and Web Sockets were spun off from the HTML5 specification. Others, such as  Geolocation, were never part of the specification at all, but browser makers and developers have associated Geolocation with  HTML5 because the specification is being implemented alongside other features.

This part of the book covers these features, with more attention given to those features that are already usable right now. We’ll also spend a chapter discussing things that are coming next. Let’s start by looking at Web Storage and Web SQL Storage, two specifications that let us store data on the client.

Remember when cookies were awesome? Neither do I. Cookies have been rather painful to deal with since they came on the scene, but we have put up with the hassle because they’ve been the only way to store information on the clients’ machines. To use them, we have to  name the cookie and set its expiration.

This involves a bunch of JavaScript code we wrap in a function so we never have to think about how it actually works, kind of like this:

/ / v i a h t t p : / / w w w . j a v a s c r i p t e r . n e t / f a q / s e t t i n g a . h t m
function S e t C o o k i e ( c o o k i e N a m e , c o o k i e V a l u e , n D a y s ) {
var t o d a y = new D a t e O ;
var e x p i r e = new D a t e O ;
if (nDays==null || nDays==0) nDays=l;
e x p i r e . s e t T i m e C t o d a y . g e t T i m e C ) + 3 6 0 0 0 0 0 * 2 4 * n D a y s ) ;
document. c o o k i e = c o o k i e N a m e + ” = ” + e s c a p e ( c o o k i e V a l u e )
+ “; expi res= ” + e x p i re . t o G M T S t r i n g O ;
}

Aside from the hard-to-remember syntax, there are also the security concerns. Some sites use cookies to track users’ surfing behavior, so users disable cookies in some fashion.

HTML5 introduced a few new options for storing data on the client:
Web Storage (using either localStorage or sessionStorage)1 and Web SQL Databases.2 They’re easy to use, incredibly powerful, and reasonably secure. Best of all, they’re  mplemented today by several browsers, including iOS’s Mobile Safari and Android 2.0’s web browser. However, they are no longer part of the HTML5 specification—they’ve been spun
off into their own specifications.

While localStorage, sessionStorage, and Web SQL Databases can’t replace cookies intended to be shared between the client and the server—like in the case of web frameworks that use the cookies to maintain state across requests—they can be used to store data that only users care about, such as visual settings or preferences. They also come in handy for building mobile applications that can run in the browser but are not connected to the Internet. Many web applications currently call back to a server to save user data, but with these new storage mechanisms, an Internet connection is no longer an absolute dependency. User data
could be stored locally and backed up when necessary.

When you combine these methods with HTML5’s new offline features, you can build complete database applications right in the browser that work on a wide variety of platforms, from desktops to iPads and Android phones. In this chapter, you’ll learn how to use these techniques to persist user settings and create a simple notes database.

In this chapter, we’ll get acquainted with the following features:

localStorage
Stores data in key/value pairs, tied to a domain, and persists
across browser sessions. [C5, F3.5, S4, IE8, 010.5, IOS, A]
sessionStorage
Stores data in key/value pairs, tied to a domain, and is erased
when a browser session ends. [C5, F3.5, S4, IE8, 010.5, IOS, A]
Web SQL Databases
Fully relational databases with support for creating tables, inserts,
updates, deletes, and selects, with transactions. Tied to a domain
and persists across sessions. [C5, S3.2, 010.5, IOS3.2, A2]
Offline Web Applications
Defines files to be cached for offline use, allowing applications to
run without an Internet connection. [C4, S4, F3.5, 010.6, IOS3.2,
A2]

 

A Platform for Web Development

A lot of the new features of HTML center around creating a better platform for web-based applications. From more descriptive tags and better cross-site and cross-window communication to animations and improved multimedia support, developers using HTML5 have a lot of new tools to build better user experiences.

More Descriptive Markup
Each version of HTML introduces some new markup, but never before have there been so many new additions that directly relate to describing content. You’ll learn about elements for defining headings, footers, navigation sections, sidebars, and articles in Chapter 2, New Structural Tags and Attributes, on page 24. You’ll also learn about meters, progress bars, and how custom data attributes can help you mark up data.

Multimedia with Less Reliance on Plug-ins
You don’t need Flash or SUverlight for video, audio, and vector graphics anymore. Although Flash-based video players are relatively simple to use, they don’t work on Apple’s mobile devices. That’s a significant
market, so you’ll need to learn how to use non-Flash video alternatives.

Better Applications
Developers have tried all kinds of things to make richer, more interactive applications on the Web, from ActiveX controls to Flash. HTML5 offers amazing features that, in some cases, completely eliminate the
need for third-party technologies.

Cross-Document Messaging
Web browsers prevent us from using scripts on one domain to affect or interact with scripts on another domain. This restriction keeps end users safe from cross-site scripting, which has been used to do all sorts
of nasty things to unsuspecting site visitors.

However, this prevents all scripts from working, even when we write them ourselves and know we can trust the content. HTML5 includes a workaround that is both safe and simple to implement.

Web Sockets
HTML5 offers support for Web Sockets, which give you a persistent connection to a server. Instead of constantly polling a back end for progress updates, your web page can subscribe to a socket, and the back end can push notifications to your users.

Client-Side Storage

We tend to think of HTML5 as a web technology, but with the addition of the Web Storage and Web SQL Database APIs, we can build applications in the browser that can persist data entirely on the client’s machine.

Better Interfaces
The user interface is such an important part of web applications, and we jump through hoops every day to make browsers do what we want. To style a table or round corners, we either use JavaScript libraries or add tons of additional markup so we can apply styles. HTML5 and CSS3 make that practice a thing of the past.

Better Forms
HTML5 promises better user interface controls. For ages, we’ve been forced to use JavaScript and CSS to construct sliders, calendar date pickers, and color pickers. These are all defined as real elements in HTML5, just like drop-downs, checkboxes, and radio buttons. Although this isn’t quite ready yet for every browser,
it’s something you need to keep your eye on, especially if you develop web-based applications. In addition to improved usability without reliance on JavaScript libraries, there’s another benefit—improved accessibility.
Screen readers and other browsers can implement these controls in specific ways so that they work easily for the disabled.

Improved Accessibility
Using the new HTML5 elements in HTML5 to clearly describe our content makes it easier for programs like screen readers to easily consume the content. A site’s navigation, for example, is much easier to find if
you can look for the nav tag instead of a specific div or unordered list. Footers, sidebars, and other content can be easily reordered or skipped altogether. Parsing pages in general becomes much less painful, which
can lead to better experiences for people relying on assistive technologies. In addition, new attributes on elements can specify the roles of elements so that screen readers can work with them easier.

Advanced Selectors
CSS3 has selectors that let you identify odd and even rows of tables, all selected check boxes, or even the last paragraph in a group. You can accomplish more with less code and less markup.

Visual Effects
Drop shadows on text and Images help bring depth to a web page, and gradients can also add dimension. CSS3 lets you add shadows and gradients to elements without resorting to background images or extra markup. In addition, you can use transformations to round corners or skew and rotate elements.

How This Works

Each chapter in this book focuses on a specific group of problems that we can solve with HTML5 and CSS3. Each chapter has an overview and a table summarizing the tags, features, or concepts covered in the chapter. The main content of each chapter is broken apart into “tips,” which introduce you to a specific concept and walk you through building a simple example using the concept. The chapters in this book are grouped topically. Rather than group things into an HTML5 part and a CSS3 part, it made more sense to group them based on the problems they solve.

Each tip contains a section called “Falling Back,” which shows you methods for addressing the users who use browsers that don’t offer HTML5 and CSS3 support. We’ll be using a variety of techniques to make these fallbacks work, from third-party libraries to our own jQuery plug-ins. These tips can be read in any order you like.

Finally, each chapter wraps up with a section called “The Future,” where we discuss how the concept can be applied as it becomes more widely adopted.

We’ll start off with a brief overview of HTML5 and CSS3 and take a look at some of the new structural tags you can use to describe your page content. Then we’ll work with forms, and you’ll get a chance to use some
of the form fields and features such as autofocus and placeholders. From there, you’ll get to play with CSS3’s new selectors so you can learn how to apply styles to elements without adding extra markup to your content.

Then we’ll explore HTML’s audio and video support, and you’ll learn how to use the canvas to draw shapes. You’ll also get to see how to use CSS3’s shadows, gradients, and transformations, as well as how to learn how to work with fonts.

In the last section, we’ll use HTML5’s client-side features such as Web Storage, Web SQL Databases, and offline support to build client-side applications. We’ll use Web Sockets to talk to a simple chat service, and you’ll see how HTML5 makes it possible to send messages and data across domains. You’ll also get a chance to play with the Geolocation API and learn how to manipulate the browser’s history. We’ll then wrap up by taking a look at a few things that aren’t immediately useful but will become important in the near future.

HTML5: The Platform vs. the Specification

HTML5 is a specification that describes some new tags and markup, as well as some wonderful JavaScript APIs, but it’s getting caught up in a whirlwind of hype and promises. Unfortunately, HTML5 the standard has evolved into HTML5 the platform, creating an awful lot of confusion among developers, customers, and even authors. In some cases, pieces from the CSS3 specification such as shadows, gradients, and transformations are being called “HTML.” Browser makers are trying to one-up each other with how much “HTML5” they support. People are starting to make strange requests like “My site will be in HTML5, right?”

For the majority of the book, we’ll focus on the HTML5 and CSS3 specifications themselves and how you can use the techniques they describe. In the last part of the book, we’ll look into a suite of closely related specifications that were once part of HTML5 but are in use right now on multiple platforms. These include Web SQL Databases, Geolocation,
and Web Sockets. Although these things aren’t technically HTML5, they can help you build incredible things when combined with HTML5 and CSS3.