Developing with WebSockets and PHP
* För alla svenskar som håller till här ber jag så hemskt mycket om ursäkt, men jag tror inte så många svenska utvecklare kommer läsa detta nämligen, därför väljer jag att skriva det på engelska.
The next big thing within web development is just starting to see the dawning of our world, namely websockets, and yes, you can bet your sweet ass on that i’ts the next big thing. It’s our next major puzzle piece for making greater websites lying right infront of us just waiting, and why is that you may ask?
Well, you know those beta versions, those tend to stay in beta for a while, and while we are all waiting for them to go stable we can just sit there and drewl over the new functionality coming with the new browser versions. In this case Websockets, which is similar to an AJAX request, but allows you to connect anywhere on any port, not just on the same domain you have your website on. It also allows you to keep the connection alive so you can send data back and forth over the same connection making this new feature massively awsome when making chats/games.
However, this functionality is so far only available in Chrome and Firefox 4-beta and it will probably be a while before we will be seing Firefox 4 pushed live, so for now, you will probably only be able to use this functionality for testing purposes if you dont want to lock all your users to Chrome.
But! Curious as I am, I have ofcourse already tried the stuff out making a small arcade game, although I will not share the game with you just yet as its not completly finished, I will share some example code so you can get going with your own stuff.
Have a look at the “Server code“, you can just run it with “php filename.php”
$errno = 0;
$errstr = "";
$s = stream_socket_server("tcp://0.0.0.0:31339", $errno, $errstr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN);
if($s == false) {
echo "FAILED ".$errno." ".$errstr."\r\n";
}else{
$clients = array();
$authed = array();
$listeners = array();
$listeners[] = $s;
while(true) {
usleep(1);
$read = array_merge(array_values($clients), array_values($listeners));
if(stream_select($read, $write = NULL, $except = NULL, 0) > 0) {
foreach($listeners as $listener) {
// Check if its a new socket or not
if(in_array($listener, $read) && !in_array($read, $clients)) {
// Accept new client
$clients[] = $newsock = @stream_socket_accept($listener);
stream_set_timeout($newsock, 1);
stream_set_blocking($newsock, 0);
echo "Accepted new client\n";
// remove the listening socket from the clients-with-data array
$key = array_search($listener, $read);
unset($read[$key]);
unset($key);
}
}
foreach($read as $socket){
// If connection isnt authed yet,
// send confirmation handshake to browser
if(!in_array($socket, $authed)) {
// Parse browsers handshake
$data = stream_get_line($socket, 9999, "\r\n\r\n");
$data .= "\r\n\r\n".fgets($socket);
if(preg_match('#GET (.*?) HTTP#', $data, $match)) {
$resource = $match[1];
}
if(preg_match("#Host: (.*?)\r\n#", $data, $match)) {
$host = $match[1];
}
if(preg_match("#Sec-WebSocket-Key1: (.*?)\r\n#", $data, $match)) {
$spaces = 0;
str_replace(' ', '', $match[1], $spaces);
$key1 = (preg_replace('#[^0-9]+#', '', $match[1])/$spaces);
}
if(preg_match("#Sec-WebSocket-Key2: (.*?)\r\n#", $data, $match)) {
$spaces = 0;
str_replace(' ', '', $match[1], $spaces);
$key2 = (preg_replace('#[^0-9]+#', '', $match[1])/$spaces);
}
if(preg_match("#Sec-WebSocket-Protocol: (.*?)\r\n#", $data, $match)) {
$protocol = $match[1];
}
if(preg_match("#Origin: (.*?)\r\n#", $data, $match)) {
$origin = $match[1];
}
if(preg_match("#\r\n\r\n(.*?)\$#", $data, $match)) {
$code = $match[1];
}
$answer = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n".
"Upgrade: WebSocket\r\n".
"Connection: Upgrade\r\n".
"Sec-WebSocket-Origin: ".$origin."\r\n".
"Sec-WebSocket-Location: ws://".$host."".$resource."\r\n".
($protocol ? "Sec-WebSocket-Protocol: ".$protocol."\r\n" : "").
"\r\n".md5(pack('N', $key1).pack('N', $key2).$code,true);
$authed[] = $socket;
fwrite($socket, $answer, strlen($answer));
echo 'Sent confirmation handshake'."\r\n";
continue;
}else{
// Get already authed connections data
$data = trim(@fgets($socket), " \r\n".chr(0).chr(255));
}
if(mb_strlen($data) == 0) {
continue;
}
echo 'Received data:'.$data."\r\n";
$nfo = stream_get_meta_data($socket);
if(!$nfo["timed_out"] && !$nfo["eof"]) {
// Put whatever you want your software to do here
// Note that when sending a msg back you have to
// Wrap the message with chr(0) and chr(255)
// Example:
// fwrite($socket, chr(0).'test'.chr(255));
}else{
@fclose($socket);
$key = array_search($socket, $clients);
unset($clients[$key]);
echo "Client timed out\n";
}
}
}
foreach($clients as $client) {
$nfo = stream_get_meta_data($client);
if($nfo["timed_out"] || $nfo["eof"]) {
@fclose($socket);
$key = array_search($socket, $clients);
unset($clients[$key]);
echo "Client timed out\n";
}
}
}
}
Heres the javascript that sends the websocket request
if ("WebSocket" in window) {
var ws = new WebSocket("ws://mincent.praxxa.com:31339");
ws.onopen = function() {
// Web Socket is connected. You can send data by send() method.
//ws.send("message to send"); ....
//alert('connected!');
ws.send("test");
alert('yes!!!');
};
ws.onerror = function(evt) { alert(evt.data); };
ws.onmessage = function (evt) { alert(evt.data); };
ws.onclose = function(evt) {
// websocket is closed.
};
} else {
alert('Your browser doesnt support websockets, try in Google Chrome!');
}






Fyll i forumläret så ringer vi upp dig!