Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- // Functions
- ////////////////////////////////////////////////////
- function ConsoleError($errorFunctionName, $socket)
- {
- return $errorFunctionName . " failed, reason: " . socket_strerror(socket_last_error($socket)) . "\r\n";
- }
- function websock_decode($data)
- {
- $bytes = $data;
- $data_length = "";
- $mask = "";
- $coded_data = "" ;
- $decoded_data = "";
- $data_length = $bytes[1] & 127;
- if ($data_length === 126)
- {
- $mask = substr($bytes, 4, 8);
- $coded_data = substr($bytes, 8);
- }
- else if ($data_length === 127)
- {
- $mask = substr($bytes, 10, 14);
- $coded_data = substr($bytes, 14);
- }
- else
- {
- $mask = substr($bytes, 2, 6);
- $coded_data = substr($bytes, 6);
- }
- for ($i = 0; $i < strlen($coded_data); $i++)
- {
- $decoded_data .= $coded_data[$i] ^ $mask[$i%4];
- }
- //echo "Server Received->".$decoded_data."\r\n";
- return $decoded_data;
- }
- function websock_encode($data, $binary = false)
- {
- $databuffer = array();
- $sendlength = strlen($data);
- $rawBytesSend = $sendlength + 2;
- $packet;
- if ($sendlength > 65535)
- {
- // 64bit
- array_pad($databuffer, 10, 0);
- $databuffer[1] = 127;
- $lo = $sendlength | 0;
- $hi = ($sendlength - $lo) / 4294967296;
- $databuffer[2] = ($hi >> 24) & 255;
- $databuffer[3] = ($hi >> 16) & 255;
- $databuffer[4] = ($hi >> 8) & 255;
- $databuffer[5] = $hi & 255;
- $databuffer[6] = ($lo >> 24) & 255;
- $databuffer[7] = ($lo >> 16) & 255;
- $databuffer[8] = ($lo >> 8) & 255;
- $databuffer[9] = $lo & 255;
- $rawBytesSend += 8;
- }
- else if ($sendlength > 125)
- {
- // 16 bit
- array_pad($databuffer, 4, 0);
- $databuffer[1] = 126;
- $databuffer[2] = ($sendlength >> 8) & 255;
- $databuffer[3] = $sendlength & 255;
- $rawBytesSend += 2;
- }
- else
- {
- array_pad($databuffer, 2, 0);
- $databuffer[1] = $sendlength;
- }
- // Set op and find
- $databuffer[0] = (128 + ($binary ? 2 : 1));
- $packet = pack('c', $databuffer[0]);
- // Clear masking bit
- //$databuffer[1] &= ~128;
- // write out the packet header
- for ($i = 1; $i < count($databuffer); $i++)
- {
- //$packet .= $databuffer[$i];
- $packet .= pack('c', $databuffer[$i]);
- }
- // write out the packet data
- for ($i = 0; $i < $sendlength; $i++)
- {
- $packet .= $data[$i];
- }
- return $packet;
- }
- /////////////////////////////////////////////////////
- $address = "localhost";
- $port = "10001";
- set_time_limit(0);
- ob_implicit_flush(true);
- $sockets = array();
- $handshakes = array();
- $sockets["listening"] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
- if ($sockets["listening"] < 0)
- {
- die(ConsoleError("socket_create()", $sockets["listening"]));
- }
- socket_set_option($sockets["listening"], SOL_SOCKET, SO_REUSEADDR, 1);
- if (!socket_bind($sockets["listening"], $address, $port))
- {
- die(ConsoleError("socket_bind()", $sockets["listening"]));
- }
- if (socket_listen($sockets["listening"], 100) < 0)
- {
- die(ConsoleError("socket_listen()", $sockets["listening"]));
- }
- echo("WebSocket server is started\r\n");
- while(true)
- {
- $readable_sockets = $sockets;
- socket_select($readable_sockets, $writable_sockets = NULL, $exceptions = NULL, NULL);
- foreach ($readable_sockets as $socket)
- {
- //Если это запрос на подключение нового клиента
- if ($socket == $sockets["listening"])
- {
- $client = socket_accept($socket);
- if ($client < 0)
- {
- echo(ConsoleError("socket_accept", $client));
- continue;
- }
- else
- {
- $sockets[] = $client;
- echo("New client try to connect\r\n");
- }
- }
- //Если это получение данных, отправленных клиентом
- else
- {
- $index = array_search($socket, $sockets);
- $len = socket_recv($socket, $buffer, 2048, 0);
- //Если это сообщение об отключении клиента
- if ($len === 0)
- {
- if ($index >= 0)
- {
- unset($sockets[$index]);
- if (isset($handshakes[$index]))
- {
- unset($handshakes[$index]);
- }
- }
- socket_close($socket);
- echo("Client disconnected\r\n");
- }
- else if ($len === false)
- {
- echo(ConsoleError("socket_recv", $socket));
- continue;
- }
- //Если это блок данных от клиента, который можно прочитать
- else
- {
- //Если мы уже выполняли "рукопожатие" с этим клиентом
- if (isset($handshakes[$index]))
- {
- //Обрабатываем сообщение $buffer от клиента $socket
- $tt = "";
- for ($i = 0; $i < strlen($buffer); $i++)
- {
- $tt .= str_pad(sprintf("%x", ord($buffer[$i])), 2, "0", STR_PAD_LEFT) . " ";
- }
- $tt .= "\r\n";
- echo("Received buffer: " . $tt);
- $temp = websock_decode($buffer);
- echo("Received message: " . $temp . "\r\n");
- $answer = websock_encode($temp);
- $tt = "";
- for ($i = 0; $i < strlen($answer); $i++)
- {
- $tt .= str_pad(sprintf("%x", ord($answer[$i])), 2, "0", STR_PAD_LEFT) . " ";
- }
- $tt .= "\r\n";
- echo("Sended buffer: " . $tt . "\r\n");
- echo("sended string: " . $answer . "\r\n");
- foreach ($sockets as $client)
- {
- if ($client != $sockets["listening"])
- {
- socket_set_nonblock($client);
- if (socket_write($client, $answer, strlen($answer)) === false)
- {
- ConsoleError("socket_write()", $client);
- }
- socket_set_block($client);
- }
- }
- }
- else
- {
- //Выполняем "рукопожатие"
- $webSocket_key = substr($buffer, strpos($buffer, "Sec-WebSocket-Key: ") + 19);
- $webSocket_key = substr($webSocket_key, 0, strpos($webSocket_key, "\r\n"));
- $webSocket_accept = $webSocket_key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
- $webSocket_accept = base64_encode(sha1($webSocket_accept, true));
- $webSocket_answer =
- "HTTP/1.1 101 Switching Protocols\r\n" .
- "Upgrade: websocket\r\n" .
- "Connection: Upgrade\r\n" .
- "Sec-WebSocket-Accept: {$webSocket_accept}\r\n\r\n" . chr(0);
- socket_write($socket, $webSocket_answer, strlen($webSocket_answer));
- $handshakes[$index] = true;
- }
- }
- }
- }
- }
- ?>
Advertisement
Add Comment
Please, Sign In to add comment