Caucho Technology

hello, world websocket in quercus/php


A "hello, world" WebSocket servlet using the Quercus PHP implementation

Demo

WebSocket Overview

WebSocket is a new browser capability being developed for HTML 5 browsers, enabling fully interactive applications. With WebSockets, both the browser and the server can send asynchronous messages over a single TCP socket, without resorting to long polling or comet.

Essentially, a WebSocket is a standard bidirectional TCP socket between the client and the server. The socket starts out as a HTTP connection and then "Upgrades" to a TCP socket after a HTTP handshake. After the handshake, either side can send data.

WebSocket handshake
GET /test HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
Origin: http://localhost/test
Host: localhost
Content-Length: 0

...

HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Server: Resin/4.0.2
WebSocket-Location: ws://localhost/websocket
WebSocket-Origin: http://localhost/test
Content-Length: 0
Date: Fri, 08 May 2009 09:51:31 GMT

...

WebSocket packets

After the WebSocket connection is established, all data is encoded in lightweight packets. While the spec defines a text packet and a binary packet format, browsers use the text packet exclusively. (Resin's HMTP uses the binary packet format.)

A text packet is the byte 0x00 followed by UTF-8 encoded data followed by a 0xff byte.

WebSocket text packet
x00 utf-8-data xff
Example: hello text packet
\x00hello, world\xff

Tutorial Description

Since the tutorial is a hello, world, the JavaScript just does the following:

  1. Connects to the Resin WebSocket servlet
  2. Sends a "hello" query to the servlet
  3. Sends a "server" query to the servlet
  4. Displays any received messages from the servlet

Files in this tutorial

FILEDESCRIPTION
client.phpclient HTML page and JavaScript
websocket.phpPHP WebSocket launcher - accepting the upgrade request
websocket-handler.phpPHP WebSocket handler - handles request messages

WebSocket JavaScript

The JavaScript for this example has been tested with the nightly build of Chromium.

Connecting to the WebSocket in JavaScript

Example: WebSocket connect in JavaScript
<?php
  $url = "ws://localhost:8080/example/websocket";
?>

<script language='javascript'>

function onopen(event) { ... }
function onmessage(event) { ... }
function onclose(event) { ... }

ws = new WebSocket("<?= $url ?>");
wsopen.ws = ws;
ws.onopen = wsopen;
ws.onmessage = wsmessage;
ws.onclose = wsclose;

</script>

Receiving WebSocket data in JavaScript

Example: receive WebSocket message
<script language='javascript'>

function wsmessage(event)
{
  data = event.data;

  alert("Received: [" + data + "]");
}

</script>

Sending WebSocket data in JavaScript

Example: send WebSocket message
<script language='javascript'>

function wsopen(event)
{
  ws = this.ws;

  ws.send("my-message");
}

ws = new WebSocket(...);
wsopen.ws = ws;
ws.onopen = wsopen;

</script>

WebSocket PHP

Resin's WebSocket PHP support requires two PHP files. The first accepts the WebSocket request and Upgrades the HTTP request. The second handles WebSocket messages.

To upgrade a HTTP socket to WebSocket, usewebsocket_start(path). The path is a PHP include path to handle the request.

Example: Upgrading to WebSocket
<?php

$ws = websocket_start("websocket-handler.php");

The WebSocket handler is the heart of the server-side implementation of websockets. It is a single-threaded listener for client events.

When a new packet is available, Resin will call the script, expecting it to read data from the client. While the handler is processing, Resin will not call it again until the first one has completed processing.

In this example, the handler reads a WebSocket text packet and sends a response.

Example: websocket-handler.php
<?php

// read the next packet from the client 
$value = websocket_read();

if ($value == "hello") {
 websocket_write("world");
} 
else if ($value == "server") {
 websocket_write("Resin PHP");
}

Demo


Copyright © 1998-2011 Caucho Technology, Inc. All rights reserved.
Resin ® is a registered trademark, and Quercustm, Ambertm, and Hessiantm are trademarks of Caucho Technology.