![](/user_photo/2706_HbeT2.jpg)
- •Contents at a Glance
- •Contents
- •Foreword
- •About the Authors
- •About the Technical Reviewer
- •Acknowledgments
- •Introduction
- •Who This Book Is For
- •An Overview of This Book
- •Example Code and Companion Web Site
- •Contacting the Authors
- •Overview of HTML5
- •The Story So Far—The History of HTML5
- •The Myth of 2022 and Why It Doesn’t Matter
- •Who Is Developing HTML5?
- •A New Vision
- •Compatibility and Paving the Cow Paths
- •Utility and the Priority of Constituencies
- •Interoperability Simplification
- •Universal Access
- •A Plugin–Free Paradigm
- •What’s In and What’s Out?
- •What’s New in HTML5?
- •New DOCTYPE and Character Set
- •New and Deprecated Elements
- •Semantic Markup
- •Simplifying Selection Using the Selectors API
- •JavaScript Logging and Debugging
- •window.JSON
- •DOM Level 3
- •Monkeys, Squirrelfish, and Other Speedy Oddities
- •Summary
- •Using the Canvas API
- •Overview of HTML5 Canvas
- •History
- •What Is a Canvas?
- •Canvas Coordinates
- •When Not to Use Canvas
- •Fallback Content
- •CSS and Canvas
- •Browser Support for HTML5 Canvas
- •Using the HTML5 Canvas APIs
- •Checking for Browser Support
- •Adding a Canvas to a Page
- •Applying Transformations to Drawings
- •Working with Paths
- •Working with Stroke Styles
- •Working with Fill Styles
- •Filling Rectangular Content
- •Drawing Curves
- •Inserting Images into a Canvas
- •Using Gradients
- •Using Background Patterns
- •Scaling Canvas Objects
- •Using Canvas Transforms
- •Using Canvas Text
- •Applying Shadows
- •Working with Pixel Data
- •Implementing Canvas Security
- •Building an Application with HTML5 Canvas
- •Practical Extra: Full Page Glass Pane
- •Practical Extra: Timing Your Canvas Animation
- •Summary
- •Working with Scalable Vector Graphics
- •Overview of SVG
- •History
- •Understanding SVG
- •Scalable Graphics
- •Creating 2D Graphics with SVG
- •Adding SVG to a Page
- •Simple Shapes
- •Transforming SVG Elements
- •Reusing Content
- •Patterns and Gradients
- •SVG Paths
- •Using SVG Text
- •Putting the Scene Together
- •Building an Interactive Application with SVG
- •Adding Trees
- •Adding the updateTrees Function
- •Adding the removeTree Function
- •Adding the CSS Styles
- •The Final Code
- •Summary
- •Working with Audio and Video
- •Overview of Audio and Video
- •Video Containers
- •Audio and Video Codecs
- •Audio and Video Restrictions
- •Browser Support for Audio and Video
- •Using the Audio and Video API
- •Checking for Browser Support
- •Accessibility
- •Understanding Media Elements
- •Working with Audio
- •Working with Video
- •Practical Extras
- •Summary
- •Using the Geolocation API
- •About Location Information
- •Latitude and Longitude Coordinates
- •Where Does Location Information Come From?
- •IP Address Geolocation Data
- •GPS Geolocation Data
- •Wi-Fi Geolocation Data
- •Cell Phone Geolocation Data
- •User–Defined Geolocation Data
- •Browser Support for Geolocation
- •Privacy
- •Triggering the Privacy Protection Mechanism
- •Dealing with Location Information
- •Using the Geolocation API
- •Checking for Browser Support
- •Position Requests
- •Building an Application with Geolocation
- •Writing the HTML Display
- •Processing the Geolocation Data
- •The Final Code
- •Practical Extras
- •What’s My Status?
- •Show Me on a Google Map
- •Summary
- •Using the Communication APIs
- •Cross Document Messaging
- •Understanding Origin Security
- •Browser Support for Cross Document Messaging
- •Using the postMessage API
- •Building an Application Using the postMessage API
- •XMLHttpRequest Level 2
- •Cross-Origin XMLHttpRequest
- •Progress Events
- •Browser Support for HTML5 XMLHttpRequest Level 2
- •Using the XMLHttpRequest API
- •Building an Application Using XMLHttpRequest
- •Practical Extras
- •Structured Data
- •Framebusting
- •Summary
- •Using the WebSocket API
- •Overview of WebSocket
- •Real-Time and HTTP
- •Understanding WebSocket
- •Writing a Simple Echo WebSocket Server
- •Using the WebSocket API
- •Checking for Browser Support
- •Basic API Usage
- •Building a WebSocket Application
- •Coding the HTML File
- •Adding the WebSocket Code
- •Adding the Geolocation Code
- •Putting It All Together
- •The Final Code
- •Summary
- •Using the Forms API
- •Overview of HTML5 Forms
- •HTML Forms Versus XForms
- •Functional Forms
- •Browser Support for HTML5 Forms
- •An Input Catalog
- •Using the HTML5 Forms APIs
- •New Form Attributes and Functions
- •Checking Forms with Validation
- •Validation Feedback
- •Building an Application with HTML5 Forms
- •Practical Extras
- •Summary
- •Working with Drag-and-Drop
- •Web Drag-and-Drop: The Story So Far
- •Overview of HTML5 Drag-and-Drop
- •The Big Picture
- •Events to Remember
- •Drag Participation
- •Transfer and Control
- •Building an Application with Drag-and-Drop
- •Getting Into the dropzone
- •Handling Drag-and-Drop for Files
- •Practical Extras
- •Customizing the Drag Display
- •Summary
- •Using the Web Workers API
- •Browser Support for Web Workers
- •Using the Web Workers API
- •Checking for Browser Support
- •Creating Web Workers
- •Loading and Executing Additional JavaScript
- •Communicating with Web Workers
- •Coding the Main Page
- •Handling Errors
- •Stopping Web Workers
- •Using Web Workers within Web Workers
- •Using Timers
- •Example Code
- •Building an Application with Web Workers
- •Coding the blur.js Helper Script
- •Coding the blur.html Application Page
- •Coding the blurWorker.js Web Worker Script
- •Communicating with the Web Workers
- •The Application in Action
- •Example Code
- •Summary
- •Using the Storage APIs
- •Overview of Web Storage
- •Browser Support for Web Storage
- •Using the Web Storage API
- •Checking for Browser Support
- •Setting and Retrieving Values
- •Plugging Data Leaks
- •Local Versus Session Storage
- •Other Web Storage API Attributes and Functions
- •Communicating Web Storage Updates
- •Exploring Web Storage
- •Building an Application with Web Storage
- •The Future of Browser Database Storage
- •The Web SQL Database
- •The Indexed Database API
- •Practical Extras
- •JSON Object Storage
- •A Window into Sharing
- •Summary
- •Overview of HTML5 Offline Web Applications
- •Browser Support for HTML5 Offline Web Applications
- •Using the HTML5 Application Cache API
- •Checking for Browser Support
- •Creating a Simple Offline Application
- •Going Offline
- •Manifest Files
- •The ApplicationCache API
- •Application Cache in Action
- •Building an Application with HTML5 Offline Web Applications
- •Creating a Manifest File for the Application Resources
- •Creating the HTML Structure and CSS for the UI
- •Creating the Offline JavaScript
- •Check for ApplicationCache Support
- •Adding the Update Button Handler
- •Add Geolocation Tracking Code
- •Adding Storage Code
- •Adding Offline Event Handling
- •Summary
- •The Future of HTML5
- •Browser Support for HTML5
- •HTML Evolves
- •WebGL
- •Devices
- •Audio Data API
- •Touchscreen Device Events
- •Peer-to-Peer Networking
- •Ultimate Direction
- •Summary
- •Index
CHAPTER 7 USING THE WEBSOCKET API
Now that we’ve got a working echo server, we need to write the client side. The web browsers implement the connecting half of the WebSocket Protocol. We can use the API from JavaScript to communicate with our simple server.
Using the WebSocket API
In this section, we’ll explore the use of WebSocket in more detail.
Checking for Browser Support
Before you use the WebSocket API, you will want to make sure there is support in the browser for what you’re about to do. This way, you can provide some alternate text, prompting the users of your application to upgrade to a more up-to-date browser. Listing 7-7 shows one way you can test for browser support.
Listing 7-7. Checking for Browser Support
function loadDemo() {
if (window.WebSocket) {
document.getElementById("support").innerHTML = "HTML5 WebSocket is supported in your browser.";
} else {
document.getElementById("support").innerHTML = "HTML5 WebSocket is not supported in your browser.";
}
}
In this example, you test for browser support in the loadDemo function, which might be called when the application’s page is loaded. A call to window.WebSocket will return the WebSocket object if it exists, or trigger the failure case if it does not. In this case, the page is updated to reflect whether there is browser support or not by updating a previously defined support element on the page with a suitable message.
Another way to see if WebSocket is supported in your browser, is to use the browser’s console (Firebug or Chrome Developer Tools for example). Figure 7-7 shows how you can test whether WebSocket is supported natively in Google Chrome (if it is not, the window.WebSocket command returns “undefined.”)
176
![](/html/2706/1189/html_AbQ0sDPLvd.78Bm/htmlconvd-1wDg8G176x1.jpg)
CHAPTER 7 USING THE WEBSOCKET API
Figure 7-7. Testing WebSocket support in Google Chrome Developer Tools
Basic API Usage
The sample code for the following examples is located on the book web site in the WebSocket section. This folder contains a websocket.html file and a broadcast.html file (and a tracker.html file used in the following section) as well as the WebSocket server code shown previously that can be run in Python.
Creating a WebSocket object and Connecting to a WebSocket Server
Using the WebSocket interface is straight-forward. To connect to an end-point, just create a new WebSocket instance, providing the new object with a URL that represents the end-point to which you wish to connect. You can use the ws:// and wss:// prefixes to indicate a WebSocket and a WebSocket Secure connection, respectively.
url = "ws://localhost:8080/echo"; w = new WebSocket(url);
When connecting a WebSocket, you have the option of listing the protocols your application can speak. The second argument to the WebSocket constructor can be a string or array of strings with the names of the “subprotocols” that your application understands and wishes to use to communicate.
w = new WebSocket(url, protocol);
You can even list several protocols:
w = new WebSocket(url, [“proto1”, “proto2”]);
Hypothetically, proto1 and proto2 are well defined, perhaps even registered and standardized, protocol names that both the client and server can understand. The server will select a preferred protocol from the list. When the socket opens, its protocol property will contain the protocol that the server chose.
onopen = function(e) {
// determine which protocol the server selected
177
CHAPTER 7 USING THE WEBSOCKET API
log(e.target.protocol)
}
Protocols you might use include Extensible Messaging and Presence Protocol (XMPP, or Jabber), Advanced Message Queuing Protocol (AMQP), Remote Frame Buffer (RFB, or VNC) and Streaming Text Oriented Messaging Protocol (STOMP). These are real-world protocols spoken by many clients and servers. Using a standard protocol ensures interoperability between web applications and servers from different organizations. It also opens the door for public WebSocket services. You can speak to a server using a known protocol. Client applications that understand the same protocol can then connect and participate.
This example does not use a standard protocol. We aren’t introducing external dependencies or taking the space to implement a complete standard protocol. As an example, it uses the WebSocket API directly, just as you would if you were starting to write code for a new protocol.
Adding Event Listeners
WebSocket programming follows an asynchronous programming model; once you have an open socket, you simply wait for events. You don’t have to actively poll the server anymore. To do this, you add callback functions to the WebSocket object to listen for events.
A WebSocket object dispatches three events: open, close, and message. The open event fires when a connection is established, the message event fires when messages are received, and the close event fires when the WebSocket connection is closed. The error event fires in response to unexpected failure. As in most JavaScript APIs, there are corresponding callbacks (onopen, onmessage, onclose, and onerror) that are called when the events are dispatched.
w.onopen = function() { log("open");
w.send("thank you for accepting this websocket request");
}
w.onmessage = function(e) { log(e.data);
}
w.onclose = function(e) { log("closed");
}
w.onerror = function(e) { log(“error”);
}
Let’s have another look at that message handler. The data attribute on the message event is a string if the WebSocket protocol message was encoded as text. For binary messages, data can be either a Blob or an ArrayBuffer, depending on the value of the WebSocket’s binaryType property.
w.binaryType = "arraybuffer"; w.onmessage = function(e) {
// data can now be either a string or an ArrayBuffer log(e.data);
}
178
CHAPTER 7 USING THE WEBSOCKET API
Sending Messages
While the socket is open (that is, after the onopen listener is called and before the onclose listener is called), you can use the send function to send messages. After sending one or more messages, you can also call close to terminate the connection, or you can also leave the connection open.
document.getElementById("sendButton").onclick = function() { w.send(document.getElementById("inputMessage").value);
}
That’s it. Bidirectional browser communication made simple. For completeness, Listing 7-8 shows the entire HTML page with the WebSocket code.
In more advanced uses of WebSocket, you may want to measure how much data is backed up in the outgoing buffer before calling send(). The bufferedAmount attribute represents the number of bytes that have been sent on the WebSocket that have not yet been written onto the network. This could be useful for throttling the rate at which the application sends data.
document.getElementById("sendButton").onclick = function() { if (w.bufferedAmount < bufferThreshold) {
w.send(document.getElementById("inputMessage").value);
}
}
In addition to strings, WebSocket can send binary data. This is especially useful to implement binary protocols, such as the standard Internet protocols typically layered on top of TCP. The WebSocket API supports sending Blob and ArrayBuffer instances as binary data.
var a = new Uint8Array([8,6,7,5,3,0,9]); w.send(a.buffer);
Listing 7-8. websocket.html Code
<!DOCTYPE html>
<title>WebSocket Test Page</title>
<script>
var log = function(s) {
if (document.readyState !== "complete") { log.buffer.push(s);
} else {
document.getElementById("output").textContent += (s + "\n")
}
}
log.buffer = [];
if (this.MozWebSocket) { WebSocket = MozWebSocket;
}
url = "ws://localhost:8080/echo"; w = new WebSocket(url);
w.onopen = function() {
179
CHAPTER 7 USING THE WEBSOCKET API
log("open");
//set the type of binary data messages to ArrayBuffer w.binaryType = "arraybuffer";
//send one string and one binary message when the socket opens w.send("thank you for accepting this WebSocket request");
var a = new Uint8Array([8,6,7,5,3,0,9]); w.send(a.buffer);
}
w.onmessage = function(e) { log(e.data.toString());
}
w.onclose = function(e) { log("closed");
}
w.onerror = function(e) { log("error");
}
window.onload = function() { log(log.buffer.join("\n"));
document.getElementById("sendButton").onclick = function() { w.send(document.getElementById("inputMessage").value);
}
}
</script>
<input type="text" id="inputMessage" value="Hello, WebSocket!"><button id="sendButton">Send</button>
<pre id="output"></pre>
Running the WebSocket Page
To test the websocket.html page that contains the WebSocket code, open a command prompt, navigate to the folder that contains the WebSocket code, and issue the following command to host the HTML file:
python -m SimpleHTTPServer 9999
Next, open another command prompt, navigate to the folder that contains the WebSocket code, and issue the following command to run the Python WebSocket server:
python websocket.py
Finally, open a browser that supports WebSocket natively and navigate to
http://localhost:9999/websocket.html.
Figure 7-8 shows the web page in action.
180
![](/html/2706/1189/html_AbQ0sDPLvd.78Bm/htmlconvd-1wDg8G180x1.jpg)
CHAPTER 7 USING THE WEBSOCKET API
Figure 7-8. websocket.html in action
The example code folder also contains a web page that connects to the broadcast service that was created in the previous section. To see that action, close the command prompt that is running the WebSocket server and navigate to the folder that contains the WebSocket code, and issue the following command to run the python WebSocket server.
python broadcast.py
Open two separate browsers that supports WebSocket natively and navigate (in each browser) to http://localhost:9999/broadcast.html.
Figure 7-9 shows the broadcast WebSocket server in action on two separate web pages.
181