2014-09-04 2 views
0

Я пытаюсь настроить WebSocket для своего веб-приложения. Я нашел некоторый документ и пример с Google, но я не очень хорошо понимаю, что я должен делать, чтобы отправлять дополнительные данные при открытии сокета.
Я хотел бы иметь массив пользователя, который содержит пользовательский сокет и идентификатор пользователя, но я не могу отправить идентификатор пользователя в JavaScript при открытии сокета и получить этот UserId в PHP на моем сервере. Мое приложение должно отправить сообщение конкретному клиенту, идентифицированному UserID (UserID хранится в БД, но я предположил, что мой клиентский код в JS обычно может отправить это сообщение).
На данный момент я список сокетов, но я хочу заменить его списком пользователей, который содержит идентификатор и сокет.WebSocket PHP + JS

PHP код сервера

$host = 'localhost'; //host 
$port = '9000'; //port 
$null = NULL; //null var 
//Create TCP/IP sream socket 
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 
//reuseable port 
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1); 

//bind socket to specified host 
socket_bind($socket, 0, $port); 

//listen to port 
socket_listen($socket); 

//create & add listning socket to the list 
$sockets = array($socket); 
$users = array(); 
//$clients = array($socket); 

//start endless loop, so that our script doesn't stop 
while (true) { 
    //manage multipal connections 
    $changed = $sockets; 
    //returns the socket resources in $changed array 
    socket_select($changed, $null, $null, 0, 10); 

    //check for new socket 
    if (in_array($socket, $changed)) { 
     $socket_new = socket_accept($socket); //accept new socket 
     // HERE I NEED USER ID BUT I DON'T FIND HOW TO GET IT 
     $clients[] = $socket_new; //add socket to client array 

     $header = socket_read($socket_new, 1024); //read data sent by the socket 
     perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake 

     socket_getpeername($socket_new, $ip); //get ip address of connected socket 
     $response = mask(json_encode(array('type' => 'system', 'message' => $ip . ' connected'))); //prepare json data 
     send_message($response); //notify all users about new connection 
     //make room for new socket 
     $found_socket = array_search($socket, $changed); 
     unset($changed[$found_socket]); 
    } 

    //loop through all connected sockets 
    foreach ($changed as $changed_socket) { 

     //check for any incomming data 
     while (socket_recv($changed_socket, $buf, 1024, 0) >= 1) { 
      $received_text = unmask($buf); //unmask data 
      $tst_msg = json_decode($received_text); //json decode 
      $user_id = $tst_msg->iduser; 
      $user_name = $tst_msg->name; //sender name 
      $user_message = $tst_msg->message; //message text 
      $user_color = $tst_msg->color; //color 
      //prepare data to be sent to client 
      $response_text = mask(json_encode(array('type' => 'usermsg', 'name' => $user_name, 'message' => $user_message, 'color' => $user_color))); 
      send_message($response_text); //send data 
      break 2; //exist this loop 
     } 

     $buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ); 
     if ($buf === false) { // check disconnected client 
      // remove client for $clients array 
      $found_socket = array_search($changed_socket, $clients); 
      socket_getpeername($changed_socket, $ip); 
      unset($clients[$found_socket]); 

      //notify all users about disconnected connection 
      $response = mask(json_encode(array('type' => 'system', 'message' => $ip . ' disconnected'))); 
      send_message($response); 
     } 
    } 
} 
// close the listening socket 
socket_close($sock); 

function send_message($msg) { 
    global $clients; 
    foreach ($clients as $changed_socket) { 
     @socket_write($changed_socket, $msg, strlen($msg)); 
    } 
    return true; 
} 

//Unmask incoming framed message 
function unmask($text) { 
    $length = ord($text[1]) & 127; 
    if ($length == 126) { 
     $masks = substr($text, 4, 4); 
     $data = substr($text, 8); 
    } elseif ($length == 127) { 
     $masks = substr($text, 10, 4); 
     $data = substr($text, 14); 
    } else { 
     $masks = substr($text, 2, 4); 
     $data = substr($text, 6); 
    } 
    $text = ""; 
    for ($i = 0; $i < strlen($data); ++$i) { 
     $text .= $data[$i]^$masks[$i % 4]; 
    } 
    return $text; 
} 

//Encode message for transfer to client. 
function mask($text) { 
    $b1 = 0x80 | (0x1 & 0x0f); 
    $length = strlen($text); 

    if ($length <= 125) 
     $header = pack('CC', $b1, $length); 
    elseif ($length > 125 && $length < 65536) 
     $header = pack('CCn', $b1, 126, $length); 
    elseif ($length >= 65536) 
     $header = pack('CCNN', $b1, 127, $length); 
    return $header . $text; 
} 

//handshake new client. 
function perform_handshaking($receved_header, $client_conn, $host, $port) { 
    $headers = array(); 
    $lines = preg_split("/\r\n/", $receved_header); 
    foreach ($lines as $line) { 
     $line = chop($line); 
     if (preg_match('/\A(\S+): (.*)\z/', $line, $matches)) { 
      $headers[$matches[1]] = $matches[2]; 
     } 
    } 

    $secKey = $headers['Sec-WebSocket-Key']; 
    $secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'))); 
    //hand shaking header 
    $upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" . 
      "Upgrade: websocket\r\n" . 
      "Connection: Upgrade\r\n" . 
      "WebSocket-Origin: $host\r\n" . 
      "WebSocket-Location: ws://$host:$port/demo/shout.php\r\n" . 
      "Sec-WebSocket-Accept:$secAccept\r\n\r\n"; 
    socket_write($client_conn, $upgrade, strlen($upgrade)); 
} 

function getSocketbyIdUser($idU) { 
    global $clients; 
    foreach ($clients as $client) { 
     if ($client->getIdUser() == $idU) { 
      return $client->getSocket(); 
     } 
    } 
    return false; 
} 

function userIsConnected($idU) { 
    global $clients; 
    return getSocketbyIdUser($idU) != false; 
} 

function getSocketsArray() { 
    global $clients; 
    $sockets[]; 
    foreach ($clients as $client) { 

     $sockets[] = $client->getSocket(); 
    } 
    return $sockets; 
} 

class Client { 

    private $idUser; 
    private $socket; 

    public function getIdUser() { 
     return self::$idUser; 
    } 

    public function getSocket() { 
     return self::$socket; 
    } 

} 

JS КОД

$(document).ready(function(){ 
     //create a new WebSocket object. 
     var wsUri = "ws://localhost:9000/server/server.php";  
     websocket = new WebSocket(wsUri); 

     websocket.onopen = function(ev) { // connection is open 
       $('#message_box').append("<div class=\"system_msg\">Connected!</div>"); //notify user 
     } 

     $('#send-btn').click(function(){ //use clicks message send button 
       var mymessage = $('#message').val(); //get message text 
       var myname = $('#name').val(); //get user name 

       if(myname == ""){ //empty name? 
         alert("Enter your Name please!"); 
         return; 
       } 
       if(mymessage == ""){ //emtpy message? 
         alert("Enter Some message Please!"); 
         return; 
       } 

       //prepare json data 
       var msg = { 
       message: mymessage, 
       name: myname, 
       color : '<?php echo $colours[$user_colour]; ?>' 
       }; 
       //convert and send data to server 
       websocket.send(JSON.stringify(msg)); 
     }); 

     //#### Message received from server? 
     websocket.onmessage = function(ev) { 
       var msg = JSON.parse(ev.data); //PHP sends Json data 
       var type = msg.type; //message type 
       var umsg = msg.message; //message text 
       var uname = msg.name; //user name 
       var ucolor = msg.color; //color 

       if(type == 'usermsg') 
       { 
         $('#message_box').append("<div><span class=\"user_name\" style=\"color:#"+ucolor+"\">"+uname+"</span> : <span class=\"user_message\">"+umsg+"</span></div>"); 
       } 
       if(type == 'system') 
       { 
         $('#message_box').append("<div class=\"system_msg\">"+umsg+"</div>"); 
       } 

       $('#message').val(''); //reset text 
     }; 

     websocket.onerror = function(ev){$('#message_box').append("<div class=\"system_error\">Error Occurred - "+ev.data+"</div>");}; 
     websocket.onclose = function(ev){$('#message_box').append("<div class=\"system_msg\">Connection Closed</div>");}; 
}); 

ответ

0

Отправить ваши дополнительные данные websocket так: ws://yoursite:port/?param1=value; В сервере:

if (preg_match("/GET (.*) HTTP/", $receved_header, $match)) { 
$root = $match[1]; 
$userid = explode('param1=', $root); 
if (!empty($userid) && array_key_exists(1, $param1)) 
$this->userid = $userid[1]; 
} 

это работает для меня. .try это