2014-01-14 62 views
2

目前,我有以下腳本:發送配置數據的WebSocket

Chat.php

<?php 
require_once 'core/Init.php'; 
$user = new User();  
$colours = array('007AFF','FF7000','FF7000','15E25F','CFC700','CFC700','CF1100','CF00BE','F00'); 
$user_colour = array_rand($colours); 
?> 
<script language="javascript" type="text/javascript"> 
    $(document).ready(function(){ 
     //create a new WebSocket object. 
     var wsUri = "ws://199.188.203.97:9000/includes/server.php"; 
     websocket = new WebSocket(wsUri); 

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

     $('#chatform').submit(function(event){ //if user clicks message send button 
      event.preventDefault(); 
      var mymessage = $('#message').val(); //get message text 
      var myname = '<?php echo $user->data()->username; ?>'; //get user name 

      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>");}; 
    }); 
</script> 
<div id="chat" class="fixed" data-current-user="<?php echo $user->data()->username; ?>" data-order-by-status="1" data-max-chat-history="25"> 

    <!-- conversation template --> 
    <div class="chat-outer"> 
     <div class="message_box" id="message_box" style="background-color: #fff;padding: 10px;margin-bottom: 10px;margin-left: 10px;height: 90%;"></div> 
     <form id="chatform"> 
      <input type="text" name="message" id="message" placeholder="Message" maxlength="80" autocomplete="off" style="width: 95%;margin-left: 10px;padding: 2px;" /> 
      <input type="submit" class="btn btn-info" value="Send"> 
     </form> 
    </div> 
    <div id="chatinner"> 
     <?php include("chatInner.php"); ?> 
    </div> 
</div> 
</div> 
</div> 

Server.php

<?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 
$clients = array($socket); 

//start endless loop, so that our script doesn't stop 
while (true) { 
    //manage multipal connections 
    $changed = $clients; 
    //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); //accpet new socket 
     $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_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)); 
} 

一切工作正常,但什麼我想要做的是有用戶名發送到服務器,所以如果有人連接,它顯示他們的用戶名而不是IP。只是想知道如何去做這件事。提前致謝!

回答

3

如果您使用其他人的腳本,它總是引用,你發現它很好的做法:d ...

編號:http://www.sanwebe.com/2013/05/chat-using-websocket-php-socket

我一直在用這個腳本玩弄藏漢,這是真正的好:d

所以,在我希望會回答你的問題......

你可以做什麼,是在websocket.onopen功能發送用戶名(格式化,使服務器能夠理解當新的用戶名發送),然後改變server.php代碼,然後通知新用戶的每個人......因此,這將是這個樣子:

Chat.php改變

websocket.onopen = function(ev) { 
     $('#message_box').append("<div class=\"system_msg\">Connected!</div>"); 
     //send username to server 
     var msg = { 
      newuser: '<?php echo $user->data()->username; ?>' 
     }; 
     websocket.send(JSON.stringify(msg)); 
    } 

Server.php改變

if (in_array($socket, $changed)) { 
    $socket_new = socket_accept($socket); 
    $clients[] = $socket_new; 

    $header = socket_read($socket_new, 1024); 
    perform_handshaking($header, $socket_new, $host, $port); 

    //remove the code that sends the IP 
    //socket_getpeername($socket_new, $ip); 
    //$response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' connected'))); 
    //send_message($response); 

    $found_socket = array_search($socket, $changed); 
    unset($changed[$found_socket]); 
} 

..

foreach ($changed as $changed_socket) { 

    while(socket_recv($changed_socket, $buf, 1024, 0) >= 1) 
    { 
     $received_text = unmask($buf); 
     $tst_msg = json_decode($received_text); 
     //check if the 'newuser' has been recieved, otherwise send a normal message 
     if(isset($tst_msg->newuser)) { 
      $response = mask(json_encode(array('type'=>'system', 'message'=>$tst_msg.' joined the room'))); 
      send_message($response); 
     } else { 
      $user_name = $tst_msg->name; 
      $user_message = $tst_msg->message; 
      $user_color = $tst_msg->color; 

      $response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color))); 
      send_message($response_text); 
     } 

     break 2; 
    } 

希望這會有幫助:D