Jump to content

Web Sockets Help Needed


jbwebdesign

Recommended Posts

Hello, i have been researching some real time functionality and i would like to create a realtime website.

 

something that can function similar to an auction.

 

for this, i would like to use web sockets but i can't figure out how to use web sockets with php.

 

can anyone help me?

 

i have some code below.....

 

server.php

 

#!/php -q
<?php  /*  >php -q server.php  */
error_reporting(E_ALL);

set_time_limit(0);
ob_implicit_flush();

$master  = WebSocket("localhost", 8752);
$sockets = array($master);
$users   = array();
$debug   = false;

while(true){
 $changed = $sockets;
 socket_select($changed,$write=NULL,$except=NULL,NULL);
 foreach($changed as $socket){
   if($socket==$master){
     $client=socket_accept($master);
     if($client<0){ console("socket_accept() failed"); continue; }
     else{ connect($client); }
   }
   else{
     $bytes = @socket_recv($socket,$buffer,2048,0);
     if($bytes==0){ disconnect($socket); }
     else{
       $user = getuserbysocket($socket);
       if(!$user->handshake){ dohandshake($user,$buffer); }
       else{ process($user,$buffer); }
     }
   }
 }
}

//---------------------------------------------------------------
function process($user,$msg){
 $action = unwrap($msg);
 say("< ".$action);
 switch($action){
   case "hello" : send($user->socket,"hello human");                       break;
   case "hi"    : send($user->socket,"zup human");                         break;
   case "name"  : send($user->socket,"my name is Multivac, silly I know"); break;
   case "age"   : send($user->socket,"I am older than time itself");       break;
   case "date"  : send($user->socket,"today is ".date("Y.m.d"));           break;
   case "time"  : send($user->socket,"server time is ".date("H:i:s"));     break;
   case "thanks": send($user->socket,"you're welcome");                    break;
   case "bye"   : send($user->socket,"bye");                               break;
   default      : send($user->socket,$action." not understood");           break;
 }
}

function send($client,$msg){
 say("> ".$msg);
 $msg = wrap($msg);
 socket_write($client,$msg,strlen($msg));
}

function WebSocket($address,$port){
 $master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP)     or die("socket_create() failed");
 socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1)  or die("socket_option() failed");
 socket_bind($master, $address, $port)                    or die("socket_bind() failed");
 socket_listen($master,20)                                or die("socket_listen() failed");
 echo "Server Started : ".date('Y-m-d H:i:s')."\n";
 echo "Master socket  : ".$master."\n";
 echo "Listening on   : ".$address." port ".$port."\n\n";
 return $master;
}

function connect($socket){
 global $sockets,$users;
 $user = new User();
 $user->id = uniqid();
 $user->socket = $socket;
 array_push($users,$user);
 array_push($sockets,$socket);
 console($socket." CONNECTED!");
}

function disconnect($socket){
 global $sockets,$users;
 $found=null;
 $n=count($users);
 for($i=0;$i<$n;$i++){
   if($users[$i]->socket==$socket){ $found=$i; break; }
 }
 if(!is_null($found)){ array_splice($users,$found,1); }
 $index = array_search($socket,$sockets);
 socket_close($socket);
 console($socket." DISCONNECTED!");
 if($index>=0){ array_splice($sockets,$index,1); }
}

function dohandshake($user,$buffer){
 console("\nRequesting handshake...");
 console($buffer);
 list($resource,$host,$origin,$strkey1,$strkey2,$data) = getheaders($buffer);
 console("Handshaking...");

 $pattern = '/[^\d]*/';
 $replacement = '';
 $numkey1 = preg_replace($pattern, $replacement, $strkey1);
 $numkey2 = preg_replace($pattern, $replacement, $strkey2);

 $pattern = '/[^ ]*/';
 $replacement = '';
 $spaces1 = strlen(preg_replace($pattern, $replacement, $strkey1));
 $spaces2 = strlen(preg_replace($pattern, $replacement, $strkey2));

 if ($spaces1 == 0 || $spaces2 == 0 || $numkey1 % $spaces1 != 0 || $numkey2 % $spaces2 != 0) {
       socket_close($user->socket);
       console('failed');
       return false;
 }

 $ctx = hash_init('md5');
 hash_update($ctx, pack("N", $numkey1/$spaces1));
 hash_update($ctx, pack("N", $numkey2/$spaces2));
 hash_update($ctx, $data);
 $hash_data = hash_final($ctx,true);

 $upgrade  = "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" .
             "\r\n" .
             $hash_data;

 socket_write($user->socket,$upgrade.chr(0),strlen($upgrade.chr(0)));
 $user->handshake=true;
 console($upgrade);
 console("Done handshaking...");
 return true;
}

function getheaders($req){
 $r=$h=$o=null;
 if(preg_match("/GET (.*) HTTP/"   ,$req,$match)){ $r=$match[1]; }
 if(preg_match("/Host: (.*)\r\n/"  ,$req,$match)){ $h=$match[1]; }
 if(preg_match("/Origin: (.*)\r\n/",$req,$match)){ $o=$match[1]; }
 if(preg_match("/Sec-WebSocket-Key2: (.*)\r\n/",$req,$match)){ $key2=$match[1]; }
 if(preg_match("/Sec-WebSocket-Key1: (.*)\r\n/",$req,$match)){ $key1=$match[1]; }
 if(preg_match("/\r\n(.*?)\$/",$req,$match)){ $data=$match[1]; }
 return array($r,$h,$o,$key1,$key2,$data);
}

function getuserbysocket($socket){
 global $users;
 $found=null;
 foreach($users as $user){
   if($user->socket==$socket){ $found=$user; break; }
 }
 return $found;
}

function     say($msg=""){ echo $msg."\n"; }
function    wrap($msg=""){ return chr(0).$msg.chr(255); }
function  unwrap($msg=""){ return substr($msg,1,strlen($msg)-2); }
function console($msg=""){ global $debug; if($debug){ echo $msg."\n"; } }

class User{
 var $id;
 var $socket;
 var $handshake;
}

?>

 

 

and client.php

 

<html>
<head>
<title>WebSocket</title>

<style>
html,body{font:normal 0.9em arial,helvetica;}
#log {width:440px; height:200px; border:1px solid #7F9DB9; overflow:auto;}
#msg {width:330px;}
</style>

<script>
var socket;

function init(){
 var host = "ws://localhost:8752/websocket/server.php";
 try{
   socket = new WebSocket(host);
   log('WebSocket - status '+socket.readyState);
   socket.onopen    = function(msg){ log("Welcome - status "+this.readyState); };
   socket.onmessage = function(msg){ log("Received: "+msg.data); };
   socket.onclose   = function(msg){ log("Disconnected - status "+this.readyState); };
 }
 catch(ex){ log(ex); }
 $("msg").focus();
}

function send(){
 var txt,msg;
 txt = $("msg");
 msg = txt.value;
 if(!msg){ alert("Message can not be empty"); return; }
 txt.value="";
 txt.focus();
 try{ socket.send(msg); log('Sent: '+msg); } catch(ex){ log(ex); }
}
function quit(){
 log("Goodbye!");
 socket.close();
 socket=null;
}

// Utilities
function $(id){ return document.getElementById(id); }
function log(msg){ $("log").innerHTML+="<br>"+msg; }
function onkey(event){ if(event.keyCode==13){ send(); } }
</script>

</head>
<body onload="init()">
<h3>WebSocket v2.00</h3>
<div id="log"></div>
<input id="msg" type="textbox" onkeypress="onkey(event)"/>
<button onclick="send()">Send</button>
<button onclick="quit()">Quit</button>
<div>Commands: hello, hi, name, age, date, time, thanks, bye</div>
</body>
</html>

 

 

the problem i have is.....

 

when i use server.php from shell, it seems to return the following:

 

Server Started : 2013-07-08 09:58:50

Master socket : Resource id #4

Listening on : localhost port 8752

 

 

 

However, when i try to use it on the Client side, it doesn't connect at all.

 

 

can someone please help me to figure out what i am doing wrong?

 

any suggestion will be appreciated.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...