2015-04-02 64 views
0

WebSockets的“不理解”错误

#!/php -q 
<?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; 
$write = NULL; 
$except = NULL; 

socket_select($changed, $write, $except, 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) { 
$key = null; 

console("\nRequesting handshake..."); 
console($buffer); 
console("Handshaking..."); 

preg_match("#Sec-WebSocket-Key: (.*?)\r\n#", $buffer, $match) && $key = $match[1]; 

$key .= "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 
$key = sha1($key); 
$key = pack('H*', $key); 
$key = base64_encode($key); 

$upgrade = 
     "HTTP/1.1 101 Switching Protocols\r\n" . 
     "Upgrade: websocket\r\n" . 
     "Connection: Upgrade\r\n" . 
     "Sec-WebSocket-Accept: {$key}\r\n\r\n"; 

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

function getheaders($header) { 
$retVal = array(); 
$fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $header)); 
foreach ($fields as $field) { 
    if (preg_match('/([^:]+): (.+)/m', $field, $match)) { 
     $match[1] = preg_replace('/(?<=^|[\x09\x20\x2D])./e', 'strtoupper("\0")', strtolower(trim($match[1]))); 
     if (isset($retVal[$match[1]])) { 
      $retVal[$match[1]] = array($retVal[$match[1]], $match[2]); 
     } else { 
      $retVal[$match[1]] = trim($match[2]); 
     } 
    } 
} 

if (preg_match("/GET (.*) HTTP/", $header, $match)) { 
    $retVal['GET'] = $match[1]; 
} 
return $retVal; 
} 
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 - status 0 
Welcome - status 1 
Sent: hi 
Disconnected - status 3 
+0

我认为你的问题是在第15行;;)在php中查找通过引用传递。 – 2015-04-02 11:38:59

+0

我知道这是在线15,这就是为什么我把它列入我的问题-_-我现在怎么修复它? – 0black0rain 2015-04-02 11:40:05

+0

satish rajak's [answer](http://stackoverflow.com/a/29412105/1364007)看起来很有前途。你不能通过值传递'null',因为它不是一个值类型。我发现[这个页面](http://php.net/manual/en/language.references.pass.php)关于在php.net上通过引用传递,而我正在寻找信息来回答你的问题。 – 2015-04-02 11:47:15

回答

0

我要声明$写入和$除了第

$write = NULL; 
$except = NULL; 

socket_select($changed, $write, $except, NULL); 

然后它工作。