Open GoogleCodeExporter opened 9 years ago
What steps will reproduce the problem? 1. Start The Server 2. Start The Client 3. Server Keep Showing Socket_connect() invalid resources some path client shows WebSocket - status 0 Disconnected - status 3 What is the expected output? What do you see instead? program should work and user can chat happily What version of the product are you using? On what operating system? 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:12345/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> server.php------------------------------------------------------------ <?php /* >php -q server.php */ error_reporting(E_ALL); set_time_limit(0); ob_implicit_flush(); $master = WebSocket("localhost",12345); $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; } ?> websocket.class.php--------------------------------------------------- <?php // Usage: $master=new WebSocket("localhost",12345); class WebSocket{ var $master; var $sockets = array(); var $users = array(); var $debug = false; function __construct($address,$port){ error_reporting(E_ALL); set_time_limit(0); ob_implicit_flush(); $this->master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() failed"); socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1) or die("socket_option() failed"); socket_bind($this->master, $address, $port) or die("socket_bind() failed"); socket_listen($this->master,20) or die("socket_listen() failed"); $this->sockets[] = $this->master; $this->say("Server Started : ".date('Y-m-d H:i:s')); $this->say("Listening on : ".$address." port ".$port); $this->say("Master socket : ".$this->master."\n"); while(true){ $changed = $this->sockets; socket_select($changed,$write=NULL,$except=NULL,NULL); foreach($changed as $socket){ if($socket==$this->master){ $client=socket_accept($this->master); if($client<0){ $this->log("socket_accept() failed"); continue; } else{ $this->connect($client); } } else{ $bytes = @socket_recv($socket,$buffer,2048,0); if($bytes==0){ $this->disconnect($socket); } else{ $user = $this->getuserbysocket($socket); if(!$user->handshake){ $this->dohandshake($user,$buffer); } else{ $this->process($user,$this->unwrap($buffer)); } } } } } } function process($user,$msg){ /* Extend and modify this method to suit your needs */ /* Basic usage is to echo incoming messages back to client */ $this->send($user->socket,$msg); } function send($client,$msg){ $this->say("> ".$msg); $msg = $this->wrap($msg); socket_write($client,$msg,strlen($msg)); $this->say("! ".strlen($msg)); } function connect($socket){ $user = new User(); $user->id = uniqid(); $user->socket = $socket; array_push($this->users,$user); array_push($this->sockets,$socket); $this->log($socket." CONNECTED!"); $this->log(date("d/n/Y ")."at ".date("H:i:s T")); } function disconnect($socket){ $found=null; $n=count($this->users); for($i=0;$i<$n;$i++){ if($this->users[$i]->socket==$socket){ $found=$i; break; } } if(!is_null($found)){ array_splice($this->users,$found,1); } $index=array_search($socket,$this->sockets); socket_close($socket); $this->log($socket." DISCONNECTED!"); if($index>=0){ array_splice($this->sockets,$index,1); } } function dohandshake($user,$buffer){ $this->log("\nRequesting handshake..."); $this->log($buffer); list($resource,$host,$origin,$key1,$key2,$l8b) = $this->getheaders($buffer); $this->log("Handshaking..."); //$port = explode(":",$host); //$port = $port[1]; //$this->log($origin."\r\n".$host); $upgrade = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n" . "Upgrade: WebSocket\r\n" . "Connection: Upgrade\r\n" . //"WebSocket-Origin: " . $origin . "\r\n" . //"WebSocket-Location: ws://" . $host . $resource . "\r\n" . "Sec-WebSocket-Origin: " . $origin . "\r\n" . "Sec-WebSocket-Location: ws://" . $host . $resource . "\r\n" . //"Sec-WebSocket-Protocol: icbmgame\r\n" . //Client doesn't send this "\r\n" . $this->calcKey($key1,$key2,$l8b) . "\r\n";// . //"\r\n"; socket_write($user->socket,$upgrade.chr(0),strlen($upgrade.chr(0))); $user->handshake=true; $this->log($upgrade); $this->log("Done handshaking..."); return true; } function calcKey($key1,$key2,$l8b){ //Get the numbers preg_match_all('/([\d]+)/', $key1, $key1_num); preg_match_all('/([\d]+)/', $key2, $key2_num); //Number crunching [/bad pun] $this->log("Key1: " . $key1_num = implode($key1_num[0]) ); $this->log("Key2: " . $key2_num = implode($key2_num[0]) ); //Count spaces preg_match_all('/([ ]+)/', $key1, $key1_spc); preg_match_all('/([ ]+)/', $key2, $key2_spc); //How many spaces did it find? $this->log("Key1 Spaces: " . $key1_spc = strlen(implode($key1_spc[0])) ); $this->log("Key2 Spaces: " . $key2_spc = strlen(implode($key2_spc[0])) ); if($key1_spc==0|$key2_spc==0){ $this->log("Invalid key");return; } //Some math $key1_sec = pack("N",$key1_num / $key1_spc); //Get the 32bit secret key, minus the other thing $key2_sec = pack("N",$key2_num / $key2_spc); //This needs checking, I'm not completely sure it should be a binary string return md5($key1_sec.$key2_sec.$l8b,1); //The result, I think } 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-Key1: (.*)\r\n/",$req,$match)){ $this->log("Sec Key1: ".$sk1=$match[1]); } if(preg_match("/Sec-WebSocket-Key2: (.*)\r\n/",$req,$match)){ $this->log("Sec Key2: ".$sk2=$match[1]); } if($match=substr($req,-8)) { $this->log("Last 8 bytes: ".$l8b=$match); } return array($r,$h,$o,$sk1,$sk2,$l8b); } function getuserbysocket($socket){ $found=null; foreach($this->users as $user){ if($user->socket==$socket){ $found=$user; break; } } return $found; } function say($msg=""){ echo $msg."\n"; } function log($msg=""){ if($this->debug){ echo $msg."\n"; } } function wrap($msg=""){ return chr(0).$msg.chr(255); } function unwrap($msg=""){ return substr($msg,1,strlen($msg)-2); } } class User{ var $id; var $socket; var $handshake; } ?> Please provide any additional information below. please help me with this i'm in lot of stress becouse of this
Original issue reported on code.google.com by sahankau...@gmail.com on 30 Nov 2011 at 6:55
sahankau...@gmail.com
Original issue reported on code.google.com by
sahankau...@gmail.com
on 30 Nov 2011 at 6:55