A detailed explanation of the use of WebSocket in PHP _php instance

Source: Internet
Author: User
Tags clear screen ming php websocket unpack

About PHP WebSocket Use of detailed annotations, for your reference.

Service side:

<?php//send users join//send1 send information//send2 exit login error_reporting (e_all ^ e_notice);
Ob_implicit_flush ();
File_put_contents (' Lz.text ', ' 123 ', file_append);
$sk =new sock (' 127.0.0.1 ', 8000);
$sk->run ();
 Class sock{public $sockets;
 Public $users;
 
 Public $master; Private $SDA =array ()//Received Data Private $slen =array ()//The total length of the data Private $sjen =array ();//The length of the received data private $ar =array ();
 
 Encryption key Private $n =array (); Public function __construct ($address, $port) {$this->master= $this->websocket ($address, $port);//resource (2,
 Socket)//server Monitor Var_dump ("Master:");
 Var_dump ($this->master); $this->sockets=array ($this->master);//array (size=1) 0 => resource (2, Socket).
 Run two PHP or so//var_dump ($this->sockets);
 File_put_contents (' Lz.text ', Var_dump ($this->sockets), file_append);
  
  The function run () {while (true) {$changes = $this->sockets;//$changes by variable 1, but $this->sockets is only stable +1;
  $write =null;
  $except =null; 1. Run the Select () system call at the given array socket with the specified timeout//2. No data is received.In a blocking state,//3. If no client comes in, it blocks the process until a client accesses it, returning 1. 4. The return of the changes at this time is not once changes.
  Although it is only a record, but is not a server but the client/*select special role:!!!!!!! Initially as Array (0=>resource (2, socket)) 1, the initial state is returned to Array (0=>resource (2, socket)).
   But socket_accept can get resource (3, Socket) 2, the initial state returned to array (0=>resource (2, socket), 1=>resource (3,socket)). The customer comes to the customer as resource (3,socket).
  
  The returned data is resource (3,socket).!!!
  * * Var_dump ($changes);
  $RR =socket_select ($changes, $write, $except, NULL);
  Var_dump ($changes);
  Var_dump ("---*---");
  Exit
  /* file_put_contents (' Lz.text ', Json_encode ($changes), file_append); File_put_contents (' lz.text ', '-----', file_append); */foreach ($changes as $sock) {//Connect host's client//$this->mas TER is always resource (2, Socket). Equivalent to a cache. In both cases, 1: empty, blocking the process.
  2: Save just receive the client. if ($sock = = $this->master) {//---here only to save data//In the socket socket has been created using socket_create (), will be with Socket_bind () name, told to listen to the connection socket_
Listen (), this function will accept incoming connections, sockets. Once the connection is successful, it will return a!! New SOCKET Resource!! That the resource can be used for communication.
If there are multiple connections on the socket, the first one will be used. If there are no pending connections, Socket_accept () willBlocking until the connection becomes now.
If a non-blocking socket has been used socket_set_blocking () or Socket_set_nonblock (), the error is returned. Returns the Socket_accept () socket resource must not be used to accept new connections. 
   The original listen to the socket socket, however, is still open and can be reused. $client =socket_accept ($this->master); Resource (3, Socket).
    To accept the request and create a child link!!
   Var_dump ($client);
   Exit
   $key =uniqid ();
   $this->sockets[]= $client;
   $this->users[$key]=array (' socket ' => $client, ' Shou ' =>false); /* Array (size=1) ' 57d607085f92a ' =>//$key Array (size=2) ' Socket ' => resource (3, Socket)//$socket Performance is the same, only through $key differentiate ' Shou ' => boolean false///file_put_contents (' Lz.text ', Json_encode ($this->user
  s), file_append); 
   }else{//---Here the server and the client send information $len = 0;
   $buffer = '; do{/* int SOCKET_RECV (resource socket, string &buf, int len, int flags) resource socket is the generated socket ST Ring &AMP;BUF is the receive buffer int len is the length you intend to receive INT flags is a flag 0x1 data should be sent out, the so-called Out-of-band data is the TCP emergency data 0x2 make useful data copy into the buffer, but not from the system buffer
   deleted in the area.
   0x4 do not route the package out. The above three items are defined in the Sock.h fileAll the same 0x8 data complete records 0x100 data processing/$l =socket_recv ($sock, $buf, 1000,0);//The original data is a slow process, to take the data at once, and calculate the length of each buf, so that the total length does not exceed the set
   Fixed value//var_dump ($l);
  Exit
   File_put_contents (' Lz.text ', ' socket_recv ', file_append);
   $len + + $l;
   $buffer. = $buf;
   }while ($l ==1000);
   $k = $this->search ($sock)//sock Return key value if ($len <7) {//sent over the message is too short, the system is judged broken, broken links. $this->send2 ($k);//user exits. 1 close this $key value corresponding to the socket, delete this key record.
                 Rearrange the sockets array objects.
   2 continue; } if (! $this->users[$k] [' Shou ']) {//To determine if the user's handshake field is true?
   Otherwise shake hands again.
   $this->woshou ($k, $buffer);
   File_put_contents (' Lz.text ', ' Woshou ', file_append); }else{///If the user has already shook hands, communicate with the user.
   I can finally send a message! $buffer = $this->uncode ($buffer, $k);
   To compile if ($buffer ==false) {continue;
   }//var_dump ($bufffer);
   Exit
   $this->send ($k, $buffer);
 A function close ($k) {socket_close ($this->users[$k [' Socket ']}}}}
 unset ($this->users[$k]);
 $this->sockets=array ($this->master); FOreach ($this->users as $v) {$this->sockets[]= $v [' socket '];
 } $this->e ("Key: $k close");
 function Search ($sock) {foreach ($this->users as $k => $v) {if ($sock = = $v [' socket ']) return $k;
 return false; The function WebSocket ($address, $port) {//server listens//creates and returns a socket resource, also known as a communication node. 
 A typical network connection is composed of 2 sockets, one running on the client and the other running on the server side. Protocol, type, specific agreement $server = socket_create (Af_inet, Sock_stream, sol_tcp); Resource (2, Socket)//file_put_contents (' Lz.text ', $server, file_append);//supplied resource is not a valid stream Reso
 Urce//return BOOL. Socket resource, protocol level, available socket options, value. $r =socket_set_option ($server, Sol_socket, SO_REUSEADDR, 1);//boolean true//bind address to socket. 
 The operation must precede the use of socket_connect () or Socket_listen () to establish a connection. $r 2=socket_bind ($server, $address, $port);//boolean true//The socket socket has been created using the socket_create () delimitation and Socket_bind () name,
 It can tell the incoming connection of the listening socket.
 $r 3=socket_listen ($server);//boolean true $this->e (' Server started: '. Date (' y-m-d h:i:s ')); $this->e (' Listening on: '. $address. ' Port '. $port);
 return $server;
 function Woshou ($k, $buffer) {//docking received buffer processing, and feedback handshake!!
 $buf = substr ($buffer, Strpos ($buffer, ' Sec-websocket-key: ') +18);
 
 $key = Trim (substr ($buf, 0,strpos ($buf, "\ r \ n")); $new _key = Base64_encode (SHA1 ($key.)
 
 258eafa5-e914-47da-95ca-c5ab0dc85b11 ", true));
 $new _message = "http/1.1 switching protocols\r\n";
 $new _message. = "upgrade:websocket\r\n";
 $new _message. = "sec-websocket-version:13\r\n";
 $new _message. = "connection:upgrade\r\n"; $new _message. = "Sec-websocket-accept:". $new _key.
 
 "\r\n\r\n"; Socket_write ($this->users[$k] [' socket '], $new _message,strlen ($new _message)),//sokcet,buffer (buffer), length $this-
 >users[$k] [' Shou ']=true;
 
 return true; 
 function Uncode ($STR, $key) {//back-compiled $mask = array (); 
 $data = ';
 $msg = Unpack (' h* ', $str); the//unpack () function unpack the data from a binary string. 
 $head = substr ($msg [1],0,2);
  if ($head = = ' Bayi ' &&!isset ($this->slen[$key])) {$len =substr ($msg [1],2,2); $len =hexdec ($Len);
  if (substr ($msg [1],2,2) = = ' Fe ') {$len =substr ($msg [1],4,4);
  $len =hexdec ($len); the//hexdec () function converts 16 to decimal.
  $msg [1]=substr ($msg [1],4);
  }else if (substr ($msg [1],2,2) = = ' ff ') {$len =substr ($msg [1],4,16);
  $len =hexdec ($len);
  $msg [1]=substr ($msg [1],16); 
  $mask [] = Hexdec (substr ($msg [1],4,2)); 
  $mask [] = Hexdec (substr ($msg [1],6,2)); 
  $mask [] = Hexdec (substr ($msg [1],8,2));
  $mask [] = Hexdec (substr ($msg [1],10,2));
  $s = 12;
 $n = 0;
  }else if ($this->slen[$key] > 0) {$len = $this->slen[$key];
  $mask = $this->ar[$key];
  $n = $this->n[$key];
 $s = 0;
 } $e = strlen ($msg [1])-2; 
  for ($i = $s; $i <= $e; $i + 2) {$data. = Chr ($mask [$n%4]^hexdec (substr ($msg [1], $i, 2)); 
 $n + +;
 
 $dlen =strlen ($data);
  if ($len > 255 && $len > $dlen +intval ($this->sjen[$key)) {$this->ar[$key]= $mask;
  $this->slen[$key]= $len;
  $this->sjen[$key]= $dlen +intval ($this->sjen[$key]);
  $this->sda[$key]= $this->sda[$key]. $data; $this->n[$key]= $n;
 return false;
  }else{unset ($this->ar[$key], $this->slen[$key], $this->sjen[$key], $this->n[$key]);
  $data = $this->sda[$key]. $data;
  unset ($this->sda[$key]);
 return $data; 
 } function code ($MSG) {//compilation $frame = Array (); 
 $frame [0] = ' 81 ';
 $len = strlen ($msg); if ($len < 126) {$frame [1] = $len <16? '
 0 '. Dechex ($len):d Echex ($len);
  }else if ($len < 65025) {$s =dechex ($len);
 $frame [1]= ' 7e '. Str_repeat (' 0 ', 4-strlen ($s)). $s;
  }else{$s =dechex ($len);
 $frame [1]= ' 7f '. Str_repeat (' 0 ', 16-strlen ($s)). $s; 
 } $frame [2] = $this->ord_hex ($msg); 
 $data = Implode (", $frame); 
 Return Pack ("h*", $data); 
 function Ord_hex ($data) {$msg = '; 
 $l = strlen ($data); 
 for ($i = 0; $i < $l; $i + +) {$msg. = Dechex (Ord ($data {$i})); 
 return $msg;
 }//user Join function Send ($k, $msg) {parse_str ($msg, $g);//parse the query string into the variable $ar =array ();
  if ($g [' type ']== ' Add ') {$this->users[$k] [' name ']= $g [' Ming '];
  $ar [' type ']= ' add '; $ar [' Name ']=$g [' Ming '];
 $key = ' all ';
  }else{$ar [' Nrong ']= $g [' nr '];
 $key = $g [' key '];
 $this->send1 ($k, $ar, $key);
 function Getusers () {$ar =array ();
 foreach ($this->users as $k => $v) {$ar []=array (' Code ' => $k, ' name ' => $v [' name ']);
 return $ar;
 //$k The Code of the sender $key the recipient's code function send1 ($k, $ar, $key = ' all ') {$ar [' code1 ']= $key;
 $ar [' Code ']= $k;
 $ar [' Time ']=date (' m-d h:i:s ');
 $str = $this->code (Json_encode ($ar));
  if ($key = = ' All ') {$users = $this->users;
  if ($ar [' type ']== ' Add ') {$ar [' type ']= ' Madd ';
  $ar [' Users ']= $this->getusers ();
  $str 1 = $this->code (Json_encode ($ar));
  Socket_write ($users [$k] [' socket '], $str 1,strlen ($str 1));//Sender unset ($users [$k]); foreach ($users as $v) {socket_write ($v [' socket '], $STR, strlen ($STR));//Recipient}}else{Socket_write ($this->users [$k] [' socket '], $STR, strlen ($STR))//Sender Socket_write ($this->users[$key] [' socket '], $STR, strlen ($STR));//Recipient}}//user
 Exit Function Send2 ($k) {$this->close ($k); $ar ['Type ']= ' rmove ';
 $ar [' Nrong ']= $k;
 $this->send1 (False, $ar, ' all '); function e ($STR) {//$path =dirname (__file__). '
 /log.txt '; $str = $str. "
 \ n ";
 Error_log ($STR, 3, $path);
 echo iconv (' Utf-8 ', ' Gbk//ignore ', $str);
 }}?>

  Client:

<!doctype html> 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.