Guest User

server websocket

a guest
Nov 11th, 2014
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.17 KB | None | 0 0
  1. <?php
  2.  
  3.     /*
  4.     |=====================================================================
  5.     | all rights to google :D
  6.     |=====================================================================
  7.     */
  8.  
  9.     class socketServer
  10.     {
  11.         /*
  12.         |=====================================================================
  13.         | THIS IS SHIT :D
  14.         |=====================================================================
  15.         */
  16.         public $null;
  17.         /*
  18.         |=====================================================================
  19.         | Hostname (localhost)
  20.         |=====================================================================
  21.         */
  22.         public $host;
  23.         /*
  24.         |=====================================================================
  25.         | Port (9000)
  26.         |=====================================================================
  27.         */
  28.         public $port;
  29.         /*
  30.         |=====================================================================
  31.         | Main Socket
  32.         |=====================================================================
  33.         */
  34.         public $socket;
  35.         /*
  36.         |=====================================================================
  37.         | Socket stream channel
  38.         |=====================================================================
  39.         */
  40.         public $stream;
  41.         /*
  42.         |=====================================================================
  43.         | Socket protocol
  44.         |=====================================================================
  45.         */
  46.         public $inc_protocol;
  47.         public $arr_protocol = array();
  48.         /*
  49.         |=====================================================================
  50.         | Callback function
  51.         |=====================================================================
  52.         */
  53.         public $callback;
  54.  
  55.         function __construct($host, $port)
  56.         {
  57.  
  58.             $this->host = $host;
  59.             $this->port = $port;
  60.  
  61.             // creating new
  62.             $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  63.  
  64.             // reuseable port
  65.             socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, 1);
  66.  
  67.             // bind socket to specified host
  68.             socket_bind($this->socket, 0, $this->port);
  69.  
  70.             // listen to port
  71.             socket_listen($this->socket);
  72.  
  73.             // create & add listning socket to the stream
  74.             $this->stream = array($this->socket);
  75.  
  76.         }
  77.  
  78.         public function start()
  79.         {
  80.  
  81.             //start endless loop, so that our script doesn't stop
  82.             while (true) {
  83.  
  84.                 //manage multipal connections
  85.                 $sub_stream = $this->stream;
  86.  
  87.                 //returns the socket resources in $changed array
  88.                 socket_select($sub_stream, $this->null, $this->null, 0, 10);
  89.  
  90.                 //check for new socket
  91.                 if (in_array($this->socket, $sub_stream)) {
  92.  
  93.                     //accpet new socket
  94.                     $socket_new = socket_accept($this->socket);
  95.  
  96.                     //add socket to stream
  97.                     $this->stream[] = $socket_new;
  98.                    
  99.                     //read data sent by the socket
  100.                     $header = socket_read($socket_new, 1024);
  101.  
  102.                     //perform websocket handshake
  103.                     $this->handshake($header, $socket_new);
  104.                    
  105.                     //make room for new socket
  106.                     $found_socket = array_search($this->socket, $sub_stream);
  107.                     unset($sub_stream[$found_socket]);
  108.  
  109.                 }
  110.  
  111.                 //loop through all connected sockets
  112.                 foreach ($sub_stream as $stream) { 
  113.                    
  114.                     //check for any incomming data
  115.                     while(socket_recv($stream, $buf, 1024, 0) >= 1)
  116.                     {
  117.  
  118.                         // decrypt buffer data
  119.                         $received = $this->decrypt_pack($buf);
  120.  
  121.                         // send buffer data
  122.                         $this->callback($received);
  123.  
  124.                         //exist this loop
  125.                         break 2;
  126.  
  127.                     }
  128.                    
  129.                     $buffer = @socket_read($stream, 1024, PHP_NORMAL_READ);
  130.  
  131.                     // check disconnected client
  132.                     if ($buffer === false) {
  133.  
  134.                         // remove client for $clients array
  135.                         $found_socket = array_search($stream, $this->stream);
  136.                         socket_getpeername($stream, $ip);
  137.                         unset($this->stream[$found_socket]);
  138.  
  139.                     }
  140.  
  141.  
  142.                 }
  143.  
  144.             }
  145.  
  146.         }
  147.  
  148.         private function handshake($received, $socket)
  149.         {
  150.  
  151.             $headers = array();
  152.             $buffer = preg_split("/\r\n/", $received);
  153.  
  154.             $pp_h = explode("\r", $received);
  155.             $pp_h = explode(": ", $pp_h[13]);
  156.             $this->inc_protocol = $pp_h[1];
  157.             if(!in_array($this->inc_protocol, $this->arr_protocol)) array_push($this->arr_protocol, $this->inc_protocol);
  158.  
  159.             foreach($buffer as $buf)
  160.             {
  161.  
  162.                 $buf = chop($buf);
  163.  
  164.                 if(preg_match('/\A(\S+): (.*)\z/', $buf, $matches))
  165.                 {
  166.  
  167.                     $headers[$matches[1]] = $matches[2];
  168.  
  169.                 }
  170.  
  171.             }
  172.  
  173.             $key = $headers['Sec-WebSocket-Key'];
  174.             $accept = base64_encode(pack('H*', sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
  175.  
  176.             $header =
  177.             "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
  178.             "Upgrade: websocket\r\n" .
  179.             "Connection: Upgrade\r\n" .
  180.             "WebSocket-Origin: ".$this->host."\r\n" .
  181.             "WebSocket-Location: ws://".$this->host.":".$this->port."\r\n".
  182.             "Sec-WebSocket-Protocol: ".$this->arr_protocol[count($this->arr_protocol)-1]."\r\n" .
  183.             "Sec-WebSocket-Accept:".$accept."\r\n\r\n"
  184.             ;
  185.  
  186.             socket_write($socket, $header, strlen($header));
  187.  
  188.         }
  189.  
  190.         private function send_pack($string)
  191.         {
  192.  
  193.             foreach($this->stream as $new_stream)
  194.             {
  195.  
  196.                 @socket_write($new_stream, $string, strlen($string));
  197.  
  198.             }
  199.  
  200.             return true;
  201.  
  202.         }
  203.  
  204.         private function encrypt_pack($pack)
  205.         {
  206.  
  207.             $crypt = 0x80 | (0x1 & 0x0f);
  208.             $length = strlen($pack);
  209.            
  210.             if($length <= 125)
  211.             {
  212.  
  213.                 $return = pack('CC', $crypt, $length);
  214.  
  215.             }
  216.  
  217.             elseif($length > 125 && $length < 65536)
  218.             {
  219.  
  220.                 $return = pack('CCn', $crypt, 126, $length);
  221.  
  222.             }
  223.                
  224.             elseif($length >= 65536)
  225.             {
  226.  
  227.                 $return = pack('CCNN', $crypt, 127, $length);
  228.  
  229.             }
  230.                
  231.             return $return.$pack;
  232.  
  233.         }
  234.  
  235.         private function decrypt_pack($pack)
  236.         {
  237.  
  238.             $length = ord($pack[1]) & 127;
  239.  
  240.             if($length == 126)
  241.             {
  242.  
  243.                 $masks = substr($pack, 4, 4);
  244.                 $data = substr($pack, 8);
  245.  
  246.             }
  247.  
  248.             elseif($length == 127)
  249.             {
  250.  
  251.                 $masks = substr($pack, 10, 4);
  252.                 $data = substr($pack, 14);
  253.  
  254.             }
  255.  
  256.             else
  257.             {
  258.  
  259.                 $masks = substr($pack, 2, 4);
  260.                 $data = substr($pack, 6);
  261.  
  262.             }
  263.  
  264.             $pack = '';
  265.  
  266.             for ($i = 0; $i < strlen($data); ++$i) {
  267.  
  268.                 $pack .= $data[$i] ^ $masks[$i%4];
  269.  
  270.             }
  271.  
  272.             return $pack;
  273.  
  274.         }
  275.  
  276.         private function callback($json)
  277.         {
  278.  
  279.             $return = array();
  280.             $receive_pack = json_decode($json);
  281.  
  282.             // check packet not empty
  283.             if(!empty($receive_pack)){
  284.  
  285.                 // get callback function name
  286.                 $callback_name = $this->callback;
  287.  
  288.                 // check callback function exist
  289.                 if(function_exists($callback_name))
  290.                 {
  291.  
  292.                     $callback_func = $callback_name($receive_pack);
  293.  
  294.                 }
  295.  
  296.                 // check callback function return value
  297.                 if(isset($callback_func) && is_array($callback_func) && !empty($callback_func))
  298.                 {
  299.  
  300.                     // callback return
  301.                     $return = $callback_func;
  302.  
  303.                 }
  304.                 else
  305.                 {
  306.  
  307.                     // default return
  308.                     foreach ($receive_pack as $key => $value) {
  309.                        
  310.                         $return[$key] = $value;
  311.  
  312.                     }
  313.  
  314.                 }
  315.  
  316.                 // sending socket packet's
  317.                 $send_pack = $this->encrypt_pack(json_encode($return));
  318.                 $this->send_pack($send_pack);
  319.  
  320.             }
  321.  
  322.         }
  323.  
  324.  
  325.     }
  326.  
  327.     function test_fsa($receive)
  328.     {
  329.  
  330.         $test = array(
  331.             'type'=>'usermsg',
  332.             'name'=>$receive->name,
  333.             'message'=>$receive->message,
  334.             'color'=>$receive->color
  335.         );
  336.  
  337.         return $test;
  338.  
  339.     }
  340.  
  341.     $socket = new socketServer('localhost', 9000);
  342.     $socket->callback = 'test_f';
  343.     $socket->start();
  344.  
  345. ?>
Add Comment
Please, Sign In to add comment