62
Realtime Communication Techniques with PHP Scott Mattocks & Chris Lewis, OnForce, Inc.

Realtime Communication Techniques with PHP

Embed Size (px)

Citation preview

Page 1: Realtime Communication Techniques with PHP

Realtime Communication Techniques with PHP

Scott Mattocks & Chris Lewis, OnForce, Inc.

Page 2: Realtime Communication Techniques with PHP

Agenda Introductions Overview

– User expectations– Problems with delivery

Techniques– Refresh– Short Polling– Long Polling– WebSockets

Q&A

Page 3: Realtime Communication Techniques with PHP

Introductions Scott Mattocks

– Senior PHP developer at OnForce, Inc.– Contributor to PEAR– Author of Pro PHP-GTK

Chris Lewis– Senior PHP developer at OnForce, Inc.– 6 years of enterprise PHP experience – 12 years of front-end web development

experience Both are contributors to the WaterSpout Real-time

Communication Server

Page 4: Realtime Communication Techniques with PHP

Overview

Example: http://www.spoutserver.com

– Click “John Locke” in the Demos section

Page 5: Realtime Communication Techniques with PHP

Overview

Users expect data to be delivered more quickly and seemlessly

– Gmail changed the way user expect to interact with websites

Loading an entire page to show a small change is slow and wasteful

Page 6: Realtime Communication Techniques with PHP

Problems with delivery

The web runs (for the most part) on HTTP

– HTTP is one way

– User asks for data

– Server sends data back

– The server can't do anything without the user asking first

Page 7: Realtime Communication Techniques with PHP

Problems with delivery Timeliness

– There is a gap between arrival of the data on the server and notification of the user.

– We want to reduce the gap without killing the servers.

Client Server

New Data

New DataBlack out

Page 8: Realtime Communication Techniques with PHP

Problems with delivery Efficiency

– How much of the transfered data is important to the user?

– Data transfer:• X bytes sent for request (GET headers)• Y bytes sent for response (body and

headers)• Z bytes of new data• Z / (X + Y) = efficiency

– We want try to send only the data that has changed and that is important to the user

Page 9: Realtime Communication Techniques with PHP

Problems with delivery

Scalability– What kind of load are we causing on

the server?– Are we holding resources (i.e.

database connections) that could be used to server other users?

– We want to do more with less

Page 10: Realtime Communication Techniques with PHP

Solutions

Refresh the page

Short Polling

Long Polling

– 1 server

– 2 servers

WebSockets

Page 11: Realtime Communication Techniques with PHP

Solutions

@gnomeboy wantto come over forsome cookies?

@gnomegirlhellz yeah!

Example: Simple twitter feed style page

Page 12: Realtime Communication Techniques with PHP

Solutions Page consists of a wrapper around message content

– Avg message size = 100 bytes– Avg page size (without images) = 4 KB– Avg request headers = 410 bytes– Avg response headers = 210 bytes

(JavaScript code examples use Prototype)

Page 13: Realtime Communication Techniques with PHP

Refresh

The same as if the user hit F5

– Reloads the entire page

– New page load adds the new message

No constant connection to the server

– Black out periods between requests

Page 14: Realtime Communication Techniques with PHP

Refresh database

web server web server

Page 15: Realtime Communication Techniques with PHP

Refresh

Difficulty

– 1 out of 10

– Use HTML or JavaScript

<meta http-equiv="refresh" content="5" />

setTimeout('window.location.reload(true)', 5000);

Page 16: Realtime Communication Techniques with PHP

Refresh

Timeliness

– Timeliness of data depends on the refresh rate

– There is an additional delay for the round trip to the server

• Includes time to send request, process request, and send response

Page 17: Realtime Communication Techniques with PHP

Refresh Efficiency (assume 10 total requests, 1 new message)

– Data transfer:

• 410 bytes sent for each request

• 4210 bytes sent for each response, 4310 for new message response

• 100 bytes of new data

• 100 / ((410 + 4210) * 10 + 100) = .0021 per message

– Server resources used

• 1 HTTP process per request (10 total)

• 1 Database connection per request (10 total)

Page 18: Realtime Communication Techniques with PHP

Short Polling Ask the server for updates since the last time you

asked

– Like a road trip with a 3 year old

– Are we there yet? Are we there yet?

No constant connection to the server

– Black out periods between requests

– Cursor required to prevent data loss

Page 19: Realtime Communication Techniques with PHP

Short Pollingdatabase

web server web server

Page 20: Realtime Communication Techniques with PHP

Short Polling Difficulty

– 5 out of 10

– AJAX

• Background request to the server checks for new messages at a timed interval

• New messages are added to DOM by JavaScript

Page 21: Realtime Communication Techniques with PHP

Short Pollingfunction poll_server() {

new Ajax.Request(this.urlPolling, {method: 'post',parameters: data,onSuccess: this.successHandler,onFailure: this.handleFailure,onException: this.handleException

});}

setInterval('poll_server()', 5000);

Page 22: Realtime Communication Techniques with PHP

Short Polling

function successHandler(trans, messages_div) { if (trans.responseText) { var json = trans.responseText.evalJSON(); if (json.message) { var msg = json.message + '<br />'; $(messages_div).insert(msg); } }}

Page 23: Realtime Communication Techniques with PHP

Short Polling

function successHandler(trans, messages_div) { if (trans.responseText) { var json = trans.responseText.evalJSON(); if (json.message) { var msg = json.message + '<br />'; $(messages_div).insert(msg); } }}

Page 24: Realtime Communication Techniques with PHP

Short Polling Timeliness

– Timeliness of data depends on the refresh rate

– There is an additional delay for the round trip to the server

• Includes time to send request, process request, and send response

Page 25: Realtime Communication Techniques with PHP

Short Polling Efficiency (assume 10 total requests, 1 new message)

– Data transfer:

• 410 bytes sent for each request

• 210 bytes sent for each empty response, 310 for new message response

• 100 bytes of new data

• 100 / ((410 + 210) * 10 + 100) = .0158 per message

– Server resources used

• 1 HTTP process per request (10 total)

• 1 Database connection per request (10 total)

Page 26: Realtime Communication Techniques with PHP

Long Polling - 1 server Ask the server for updates since the last time you

asked

– Server does not respond until a new message has arrived

No constant connection to the server

– Black out periods between sending response and next request

– Cursor required to prevent data loss

Page 27: Realtime Communication Techniques with PHP

Long Polling – 1 server

database

web server web server

Page 28: Realtime Communication Techniques with PHP

Long Polling – 1 server Difficulty – Client side

– 5 out of 10

– AJAX

• Background request to the server checks for new messages and waits for responses

• New messages are added to DOM by JavaScript

Page 29: Realtime Communication Techniques with PHP

Long Polling – 1 server Difficulty – Server side

– 5 out of 10

– Continuously loop checking for new messages

– Break out of loop when new message arrives

Page 30: Realtime Communication Techniques with PHP

Long Polling – 1 server

function poll_server() {

new Ajax.Request(this.urlPolling, {

method: 'post',

parameters: data,

onSuccess: this.successHandler,

onFailure: this.handleFailure,

onException: this.handleException

});

}

document.observe('dom:loaded', poll_server);

Page 31: Realtime Communication Techniques with PHP

Long Polling – 1 server

function successHandler(trans, messages_div) { if (trans.responseText) { var json = trans.responseText.evalJSON(); if (json.message) { var msg = json.message + '<br />'; $(messages_div).insert(msg); } }

poll_server();}

Page 32: Realtime Communication Techniques with PHP

Long Polling – 1 server

<?php$query = 'SELECT message FROM messages WHERE dateadded > ?';$stmt = $pdo->prepare($query);

while (true) { $message = $stmt->execute($cursor_date);

if (!empty($message)) { echo json_encode($message); break; }}?>

Page 33: Realtime Communication Techniques with PHP

Long Polling – 1 server Timeliness

– Near real-time– As soon as a message shows up on the

server, it is sent to the waiting client– Black out period between sending response

and making new request can add some delay

Page 34: Realtime Communication Techniques with PHP

Long Polling – 1 server Efficiency (1 request, 1 new message)

– Data transfer:• 410 bytes sent for request• 310 bytes for new message response• 100 bytes of new data• 100 / (410 + 310) = .138 per

message– Server resources used

• 1 HTTP process• 1 Database connection

Page 35: Realtime Communication Techniques with PHP

Long Polling – 2 servers 2 servers work together to use fewer resources

– Main web server handles initial page request

– Main server informs polling server when new message arrives

– Polling server informs client No constant connection to server

– Black out periods between sending response and next request

– Cursor required to prevent data loss

Page 36: Realtime Communication Techniques with PHP

Long Polling – 2 servers

web server polling server

HTTP

XHR over HTTP

Page 37: Realtime Communication Techniques with PHP

Long Polling – 2 servers Difficulty – Client side

– 5 out of 10– AJAX

• Background request to the server checks for new messages and waits for responses

• New messages are added to DOM by JavaScript

Page 38: Realtime Communication Techniques with PHP

Long Polling – 2 servers Difficulty – Server side

– 8 out of 10– Web server makes cURL call to polling

server when a new message is added– Polling server determines who message is

for and sends the response to the waiting connection

Page 39: Realtime Communication Techniques with PHP

Long Polling – 2 servers

function poll_server() {

new Ajax.Request(this.urlPolling, {

method: 'post',

parameters: data,

onSuccess: this.successHandler,

onFailure: this.handleFailure,

onException: this.handleException

});

}

document.observe('dom:loaded', poll_server);

Page 40: Realtime Communication Techniques with PHP

Long Polling – 2 servers

function successHandler(trans, messages_div) { if (trans.responseText) { var json = trans.responseText.evalJSON(); if (json.message) { var msg = json.message + '<br />'; $(messages_div).insert(msg); } }

poll_server();}

Page 41: Realtime Communication Techniques with PHP

Long Polling – 2 serversMain Web Server

Polling Server

<?php$query = 'INSERT INTO messages VALUES (?, ?)';$stmt = $pdo->prepare($query);$stmt->prepare($message, $date);$polling_server->send($message);?>

<?phpforeach ($this->waiting as $connection){ $connection->respond($message);}?>

Page 42: Realtime Communication Techniques with PHP

Long Polling – 2 servers Timeliness

– Near real-time– As soon as a message shows up on the

server, it is sent to the waiting client– Black out period between sending response

and making new request can add some delay

Page 43: Realtime Communication Techniques with PHP

Long Polling – 2 servers Efficiency (1 request, 1 new message)

– Data transfer:• 410 bytes sent for request• 310 bytes for new message response• 100 bytes of new data• 100 / (410 + 310) = .138 per

message– Server resources used

• 1 HTTP process on polling server per message

• 0 Database connections

Page 44: Realtime Communication Techniques with PHP

WebSockets

According to http://en.wikipedia.org/wiki/WebSocket:

„WebSockets is a technology providing for bi-directional, full-duplex communications channels, over a single Transmission Control Protocol (TCP) socket, designed to be implemented in web browsers and web servers”

Page 45: Realtime Communication Techniques with PHP

WebSockets WebSockets allow server to push data to client Connection established via client-initiated

handshake After handshake, both the client and the server

can send and recieve data

– Server can send data without the client asking for it first

Page 46: Realtime Communication Techniques with PHP

WebSockets Builds off of 2 server long polling

– Main web server communicates with event server

Constant connection between client and server

– No black out periods

– No need for cursor

Page 47: Realtime Communication Techniques with PHP

WebSockets

web server WebSocket server

JSON via WebSockets

Page 48: Realtime Communication Techniques with PHP

WebSockets Difficulty – Client side

– 5 out of 10– WebSocket API

• Connection established• onMessage events fired when new

data comes in from the server• New messages are added to DOM by

JavaScript

Page 49: Realtime Communication Techniques with PHP

WebSockets Difficulty – Server side

– 8 out of 10– Web server makes cURL call to WebSocket

server when a new message is added– WebSocket server determines who

message is for and sends the response to the waiting connection

Page 50: Realtime Communication Techniques with PHP

WebSockets

function poll_server() {

var socket = new WebSocket('ws://example.com/');

socket.onmessage = function (response) {

successHandler(response, 'message_errors');

}

}

document.observe('dom:loaded', poll_server);

Page 51: Realtime Communication Techniques with PHP

WebSockets

function successHandler(trans, messages_div) { if (trans.data) { var json = trans.data.evalJSON(); if (json.message) { var msg = json.message + '<br />'; $(messages_div).insert(msg); } }}

Page 52: Realtime Communication Techniques with PHP

WebSocketsMain Web Server

WebSocket Server

<?php$query = 'INSERT INTO messages VALUES (?, ?)';$stmt = $pdo->prepare($query);$stmt->prepare($message, $date);$polling_server->send($message);?>

<?phpforeach ($this->waiting as $connection){ $connection->respond($message);}?>

Page 53: Realtime Communication Techniques with PHP

WebSockets Timeliness

– Real-time– As soon as a message shows up on the

server, it is sent to the waiting client– No black out period

Page 54: Realtime Communication Techniques with PHP

WebSockets Post Handshake Efficiency

– Data transfer:• 0 bytes sent for request• 100 bytes for new message response• 100 bytes of new data• 100 / 100 = 1.000 per message

– Server resources used• 1 process on WebSocket server• 0 Database connections

Page 55: Realtime Communication Techniques with PHP

WebSockets

Efficiency Demo– http://spoutserver.com/demos/compare

Comparison– Refresh: .0021– Short Polling: .0158– Long Polling: .138– WebSockets: 1.00

Page 56: Realtime Communication Techniques with PHP

WaterSpout Lightweight HTTP server

– Static files– Dynamic content (PHP)

Best used as part of event-driven server pair– Can function as both ends

Handles WebSockets and long polling Written in PHP

Page 57: Realtime Communication Techniques with PHP

WaterSpout Two types of connections

– Listeners– Updates

When an update comes in the appropriate listeners are notified

– Custom controllers define which listeners should be notified

Page 58: Realtime Communication Techniques with PHP

WaterSpout - Listeners<?php

public function listen() {

// Handle cursor for long polling fall back.

// ...

$this->dispatcher->add_listener($this);

}

?>

Page 59: Realtime Communication Techniques with PHP

WaterSpout - Dispatcher<?php/* Called every .25 seconds on all waiting listeners */public function process_event(Controller $mover = null) { $key = array_search((int) $this->_cursor, array_keys(self::$_commands));

if ($key === false && !is_null($this->_cursor)) { return; }

$commands = array_slice(self::$_commands, $key); if (empty($commands)) { return; }

$response = new HTTPResponse(200); $body = array('__URI__' => $this->uri, 'commands' => $commands, 'cursor' => end(array_keys(self::$_commands)) + 1 ); $response->set_body($body, true);

$this->write($response); $this->_cursor = (int) end(array_keys(self::$_commands)) + 1;}?>

Page 60: Realtime Communication Techniques with PHP

WaterSpout vs Apache/Nginx Neither Apache nor Nginx has a way for one

process to notify the listeners– You need to put the incoming update into

some shared location (mysql, memcache, etc)

– Listeners have to poll the shared location • Heavy• Slows down timeliness

WaterSpout solves this by letting updates notify listeners

Page 61: Realtime Communication Techniques with PHP

WebSockets

Resources– http://dev.w3.org/html5/websockets/– http://en.wikipedia.org/wiki/Web_Sockets– http://www.spoutserver.com/

Page 62: Realtime Communication Techniques with PHP

Questions? Contact

[email protected] Twitter

– @spoutserver Feedback

– http://joind.in/talk/view/1748 Slides

– http://www.slideshare.net/spoutserver