PHP:
скопировать код в буфер обмена
скопировать код в буфер обмена
- <?PHP
- class Server
- {
- var $host;
- var $port;
- var $socket;
- var $model;
- var $clients;
- function __construct($host,$port)
- {
- $this->host = $host;
- $this->port = $port;
- $this->socket=null;
- $this->model = new Model_server();
- }
- public function run() //Запуск сервера
- {
- $this->start();
- $null=null;
- do
- {
- $read = $this->clients;
- {
- continue;
- }
- {
- // accept the client, and add him to the $clients array
- // send the client a welcome message
- $this->handshake($data,$newsock);
- $msg = $newsock." connected to the server";
- $this->send($msg);
- $msg = "<hr>".$msg."<hr>\n";
- $this->console($msg);
- //socket_getpeername($newsock, $ip);
- //echo " Client ip: {$ip}\n<hr>";
- // remove the listening socket from the clients-with-data array
- }
- foreach ($read as $read_sock)
- {
- {
- continue;
- }
- // проверка подключен ли пользователь
- if ($data === false)
- {
- // удаление клиента из массива
- $this->close($read_sock);
- continue;
- }
- else
- {
- // декодируем сообщение
- $data = $this->decode($data);
- if($data['payload']=='close')
- {
- $this->close($read_sock);
- continue;
- }
- elseif($data['payload']=="online")
- {
- }
- else
- {
- if($data['payload']!="")
- {
- if($msg!=' ' && $msg!="")
- {
- $msg = $read_sock." Say: ".$msg;
- $this->send($msg);
- $this->console($msg."<br />\n");
- }
- }
- }
- }
- }
- $this->event();
- }
- while(true);
- //
- $this->shutdown();
- }
- //////////////////////////////////////////////////////////////
- private function console($msg,$decode=false) //вывод сообщения присланные клиентом на сервере
- {
- }
- //////////////////////////////////////////////////////////////
- private function send($msg,$type = 'text', $masked = false)//Отправка сообщения пользователю
- {
- $msg = $this->encode($msg,$type,$masked);
- $i=1;
- $num=0;
- foreach ($this->clients as $read_sock)
- {
- if($num>=1)
- {
- }
- $num++;
- }
- }
- /////////////////////////////////////////////////////////////
- private function sendMessage($msg,$read_sock,$type = 'text', $masked = false)//Отправка сообщения пользователю
- {
- $msg = $this->encode($msg,$type,$masked);
- }
- //////////////////////////////////////////////////////////////
- private function close($read_sock) //Закрывает конкретное соединение
- {
- {
- //socket_close($read_sock);
- {
- }
- $this->console($read_sock." Disconnected <br />");
- $this->send($read_sock." Disconnected");
- }
- }
- //////////////////////////////////////////////////////////////
- private function shutdown() //Остановка всего сервера
- {
- {
- $this->console("<br /><hr>Server shutdown---OK <br /><hr>");
- return;
- }
- }
- //////////////////////////////////////////////////////////////
- private function start()
- {
- $this->console("-=SERVER v2.1=-<hr>\n");
- $this->console("Socket create ------");
- {
- }
- else
- {
- $this->console("OK<br />\n");
- }
- $this->console("Socket bind --------");
- //привязываем его к указанным ip и порту
- {
- }
- else
- {
- $this->console("OK <br />\n");
- }
- socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, 1);//разрешаем использовать один порт для нескольких соединений
- $this->console("Socket listening-----");
- {
- }
- else
- {
- $this->console("OK <br />\n");
- }
- $this->console("Server started-------OK<hr>\n");
- //
- }
- //////////////////////////////////////////////////////////////
- private function handshake($receved_header,$client_conn)//выполняет рукопожатие сервера и клиента
- {
- foreach($lines as $line)
- {
- {
- $headers[$matches[1]] = $matches[2];
- }
- }
- $secKey = $headers['Sec-WebSocket-Key'];
- //hand shaking header
- $upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
- "Upgrade: websocket\r\n" .
- "Connection: Upgrade\r\n" .
- "Sec-WebSocket-Origin: http://$this->host\r\n" .
- "Sec-WebSocket-Location: ws://$this->host:$this->port\r\n".
- "Sec-WebSocket-Accept: $secAccept\r\n\r\n";
- }
- //////////////////////////////////////////////////////////////
- private function decode($data) //Декорирует сообщение пришедшее от пользователся
- {
- $payloadLength = '';
- $mask = '';
- $unmaskedPayload = '';
- // estimate frame type:
- $isMasked = ($secondByteBinary[0] == '1') ? true : false;
- // close connection if unmasked frame is received:
- if($isMasked === false)
- {
- //$this->close(1002);
- }
- switch($opcode)
- {
- // text frame:
- case 1:
- $decodedData['type'] = 'text';
- break;
- case 2:
- $decodedData['type'] = 'binary';
- break;
- // connection close frame:
- case 8:
- $decodedData['type'] = 'close';
- break;
- // ping frame:
- case 9:
- $decodedData['type'] = 'ping';
- break;
- // pong frame:
- case 10:
- $decodedData['type'] = 'pong';
- break;
- default:
- // Close connection on unknown opcode:
- //$this->close(1003);
- break;
- }
- if($payloadLength === 126)
- {
- $payloadOffset = 8;
- }
- elseif($payloadLength === 127)
- {
- $payloadOffset = 14;
- $tmp = '';
- for($i = 0; $i < 8; $i++)
- {
- }
- }
- else
- {
- $payloadOffset = 6;
- $dataLength = $payloadLength + $payloadOffset;
- }
- /**
- * We have to check for large frames here. socket_recv cuts at 1024 bytes
- * so if websocket-frame is > 1024 bytes we have to wait until whole
- * data is transferd.
- */
- {
- return false;
- }
- if($isMasked === true)
- {
- for($i = $payloadOffset; $i < $dataLength; $i++)
- {
- $j = $i - $payloadOffset;
- {
- $unmaskedPayload .= $data[$i] ^ $mask[$j % 4];
- }
- }
- $decodedData['payload'] = $unmaskedPayload;
- }
- else
- {
- $payloadOffset = $payloadOffset - 4;
- }
- return $decodedData;
- }
- //////////////////////////////////////////////////////////////
- private function encode($payload, $type, $masked)//Кодирует сообщение перед отправкой пользователю
- {
- $frame = '';
- switch($type)
- {
- case 'text':
- // first byte indicates FIN, Text-Frame (10000001):
- $frameHead[0] = 129;
- break;
- case 'close':
- // first byte indicates FIN, Close Frame(10001000):
- $frameHead[0] = 136;
- break;
- case 'ping':
- // first byte indicates FIN, Ping frame (10001001):
- $frameHead[0] = 137;
- break;
- case 'pong':
- // first byte indicates FIN, Pong frame (10001010):
- $frameHead[0] = 138;
- break;
- }
- // set mask and payload length (using 1, 3 or 9 bytes)
- if($payloadLength > 65535)
- {
- $frameHead[1] = ($masked === true) ? 255 : 127;
- for($i = 0; $i < 8; $i++)
- {
- }
- // most significant bit MUST be 0 (close connection if frame too big)
- if($frameHead[2] > 127)
- {
- //$this->close(1004);
- return false;
- }
- }
- elseif($payloadLength > 125)
- {
- $frameHead[1] = ($masked === true) ? 254 : 126;
- }
- else
- {
- $frameHead[1] = ($masked === true) ? $payloadLength + 128 : $payloadLength;
- }
- // convert frame-head to string:
- {
- }
- if($masked === true)
- {
- // generate a random mask:
- for($i = 0; $i < 4; $i++)
- {
- }
- }
- // append payload to frame:
- for($i = 0; $i < $payloadLength; $i++)
- {
- $frame .= ($masked === true) ? $payload[$i] ^ $mask[$i % 4] : $payload[$i];
- }
- return $frame;
- }
- }