Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /*
- |=====================================================================
- | all rights to google :D
- |=====================================================================
- */
- class socketServer
- {
- /*
- |=====================================================================
- | THIS IS SHIT :D
- |=====================================================================
- */
- public $null;
- /*
- |=====================================================================
- | Hostname (localhost)
- |=====================================================================
- */
- public $host;
- /*
- |=====================================================================
- | Port (9000)
- |=====================================================================
- */
- public $port;
- /*
- |=====================================================================
- | Main Socket
- |=====================================================================
- */
- public $socket;
- /*
- |=====================================================================
- | Socket stream channel
- |=====================================================================
- */
- public $stream;
- /*
- |=====================================================================
- | Socket protocol
- |=====================================================================
- */
- public $inc_protocol;
- public $arr_protocol = array();
- /*
- |=====================================================================
- | Callback function
- |=====================================================================
- */
- public $callback;
- function __construct($host, $port)
- {
- $this->host = $host;
- $this->port = $port;
- // creating new
- $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
- // reuseable port
- socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, 1);
- // bind socket to specified host
- socket_bind($this->socket, 0, $this->port);
- // listen to port
- socket_listen($this->socket);
- // create & add listning socket to the stream
- $this->stream = array($this->socket);
- }
- public function start()
- {
- //start endless loop, so that our script doesn't stop
- while (true) {
- //manage multipal connections
- $sub_stream = $this->stream;
- //returns the socket resources in $changed array
- socket_select($sub_stream, $this->null, $this->null, 0, 10);
- //check for new socket
- if (in_array($this->socket, $sub_stream)) {
- //accpet new socket
- $socket_new = socket_accept($this->socket);
- //add socket to stream
- $this->stream[] = $socket_new;
- //read data sent by the socket
- $header = socket_read($socket_new, 1024);
- //perform websocket handshake
- $this->handshake($header, $socket_new);
- //make room for new socket
- $found_socket = array_search($this->socket, $sub_stream);
- unset($sub_stream[$found_socket]);
- }
- //loop through all connected sockets
- foreach ($sub_stream as $stream) {
- //check for any incomming data
- while(socket_recv($stream, $buf, 1024, 0) >= 1)
- {
- // decrypt buffer data
- $received = $this->decrypt_pack($buf);
- // send buffer data
- $this->callback($received);
- //exist this loop
- break 2;
- }
- $buffer = @socket_read($stream, 1024, PHP_NORMAL_READ);
- // check disconnected client
- if ($buffer === false) {
- // remove client for $clients array
- $found_socket = array_search($stream, $this->stream);
- socket_getpeername($stream, $ip);
- unset($this->stream[$found_socket]);
- }
- }
- }
- }
- private function handshake($received, $socket)
- {
- $headers = array();
- $buffer = preg_split("/\r\n/", $received);
- $pp_h = explode("\r", $received);
- $pp_h = explode(": ", $pp_h[13]);
- $this->inc_protocol = $pp_h[1];
- if(!in_array($this->inc_protocol, $this->arr_protocol)) array_push($this->arr_protocol, $this->inc_protocol);
- foreach($buffer as $buf)
- {
- $buf = chop($buf);
- if(preg_match('/\A(\S+): (.*)\z/', $buf, $matches))
- {
- $headers[$matches[1]] = $matches[2];
- }
- }
- $key = $headers['Sec-WebSocket-Key'];
- $accept = base64_encode(pack('H*', sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
- $header =
- "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
- "Upgrade: websocket\r\n" .
- "Connection: Upgrade\r\n" .
- "WebSocket-Origin: ".$this->host."\r\n" .
- "WebSocket-Location: ws://".$this->host.":".$this->port."\r\n".
- "Sec-WebSocket-Protocol: ".$this->arr_protocol[count($this->arr_protocol)-1]."\r\n" .
- "Sec-WebSocket-Accept:".$accept."\r\n\r\n"
- ;
- socket_write($socket, $header, strlen($header));
- }
- private function send_pack($string)
- {
- foreach($this->stream as $new_stream)
- {
- @socket_write($new_stream, $string, strlen($string));
- }
- return true;
- }
- private function encrypt_pack($pack)
- {
- $crypt = 0x80 | (0x1 & 0x0f);
- $length = strlen($pack);
- if($length <= 125)
- {
- $return = pack('CC', $crypt, $length);
- }
- elseif($length > 125 && $length < 65536)
- {
- $return = pack('CCn', $crypt, 126, $length);
- }
- elseif($length >= 65536)
- {
- $return = pack('CCNN', $crypt, 127, $length);
- }
- return $return.$pack;
- }
- private function decrypt_pack($pack)
- {
- $length = ord($pack[1]) & 127;
- if($length == 126)
- {
- $masks = substr($pack, 4, 4);
- $data = substr($pack, 8);
- }
- elseif($length == 127)
- {
- $masks = substr($pack, 10, 4);
- $data = substr($pack, 14);
- }
- else
- {
- $masks = substr($pack, 2, 4);
- $data = substr($pack, 6);
- }
- $pack = '';
- for ($i = 0; $i < strlen($data); ++$i) {
- $pack .= $data[$i] ^ $masks[$i%4];
- }
- return $pack;
- }
- private function callback($json)
- {
- $return = array();
- $receive_pack = json_decode($json);
- // check packet not empty
- if(!empty($receive_pack)){
- // get callback function name
- $callback_name = $this->callback;
- // check callback function exist
- if(function_exists($callback_name))
- {
- $callback_func = $callback_name($receive_pack);
- }
- // check callback function return value
- if(isset($callback_func) && is_array($callback_func) && !empty($callback_func))
- {
- // callback return
- $return = $callback_func;
- }
- else
- {
- // default return
- foreach ($receive_pack as $key => $value) {
- $return[$key] = $value;
- }
- }
- // sending socket packet's
- $send_pack = $this->encrypt_pack(json_encode($return));
- $this->send_pack($send_pack);
- }
- }
- }
- function test_fsa($receive)
- {
- $test = array(
- 'type'=>'usermsg',
- 'name'=>$receive->name,
- 'message'=>$receive->message,
- 'color'=>$receive->color
- );
- return $test;
- }
- $socket = new socketServer('localhost', 9000);
- $socket->callback = 'test_f';
- $socket->start();
- ?>
Add Comment
Please, Sign In to add comment