Пример #1
0
 /**
  * Websocket handshake.
  * @param string $buffer
  * @param TcpConnection $connection
  * @return int
  */
 protected static function dealHandshake($buffer, $connection)
 {
     // HTTP protocol.
     if (0 === strpos($buffer, 'GET')) {
         // Find \r\n\r\n.
         $heder_end_pos = strpos($buffer, "\r\n\r\n");
         if (!$heder_end_pos) {
             return 0;
         }
         // Get Sec-WebSocket-Key.
         $Sec_WebSocket_Key = '';
         if (preg_match("/Sec-WebSocket-Key: *(.*?)\r\n/i", $buffer, $match)) {
             $Sec_WebSocket_Key = $match[1];
         } else {
             $connection->send("HTTP/1.1 400 Bad Request\r\n\r\n<b>400 Bad Request</b><br>Sec-WebSocket-Key not found.<br>This is a WebSocket service and can not be accessed via HTTP.", true);
             $connection->close();
             return 0;
         }
         // Calculation websocket key.
         $new_key = base64_encode(sha1($Sec_WebSocket_Key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));
         // Handshake response data.
         $handshake_message = "HTTP/1.1 101 Switching Protocols\r\n";
         $handshake_message .= "Upgrade: websocket\r\n";
         $handshake_message .= "Sec-WebSocket-Version: 13\r\n";
         $handshake_message .= "Connection: Upgrade\r\n";
         $handshake_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";
         // Mark handshake complete..
         $connection->websocketHandshake = true;
         // Websocket data buffer.
         $connection->websocketDataBuffer = '';
         // Current websocket frame length.
         $connection->websocketCurrentFrameLength = 0;
         // Current websocket frame data.
         $connection->websocketCurrentFrameBuffer = '';
         // Consume handshake data.
         $connection->consumeRecvBuffer(strlen($buffer));
         // Send handshake response.
         $connection->send($handshake_message, true);
         // There are data waiting to be sent.
         if (!empty($connection->tmpWebsocketData)) {
             $connection->send($connection->tmpWebsocketData, true);
             $connection->tmpWebsocketData = '';
         }
         // blob or arraybuffer
         if (empty($connection->websocketType)) {
             $connection->websocketType = self::BINARY_TYPE_BLOB;
         }
         // Try to emit onWebSocketConnect callback.
         if (isset($connection->onWebSocketConnect)) {
             self::parseHttpHeader($buffer);
             try {
                 call_user_func($connection->onWebSocketConnect, $connection, $buffer);
             } catch (\Exception $e) {
                 echo $e;
                 exit(250);
             }
             $_GET = $_COOKIE = $_SERVER = array();
         }
         return 0;
     } elseif (0 === strpos($buffer, '<polic')) {
         $policy_xml = '<?xml version="1.0"?><cross-domain-policy><site-control permitted-cross-domain-policies="all"/><allow-access-from domain="*" to-ports="*"/></cross-domain-policy>' . "";
         $connection->send($policy_xml, true);
         $connection->consumeRecvBuffer(strlen($buffer));
         return 0;
     }
     // Bad websocket handshake request.
     $connection->send("HTTP/1.1 400 Bad Request\r\n\r\n<b>400 Bad Request</b><br>Invalid handshake data for websocket. ", true);
     $connection->close();
     return 0;
 }
Пример #2
0
 /**
  * 处理websocket握手
  * @param string $buffer
  * @param TcpConnection $connection
  * @return int
  */
 protected static function dealHandshake($buffer, $connection)
 {
     // 握手阶段客户端发送HTTP协议
     if (0 === strpos($buffer, 'GET')) {
         // 判断\r\n\r\n边界
         $heder_end_pos = strpos($buffer, "\r\n\r\n");
         if (!$heder_end_pos) {
             return 0;
         }
         // 解析Sec-WebSocket-Key
         $Sec_WebSocket_Key = '';
         if (preg_match("/Sec-WebSocket-Key: *(.*?)\r\n/", $buffer, $match)) {
             $Sec_WebSocket_Key = $match[1];
         }
         $new_key = base64_encode(sha1($Sec_WebSocket_Key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));
         // 握手返回的数据
         $new_message = "HTTP/1.1 101 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";
         $connection->handshake = true;
         $connection->consumeRecvBuffer(strlen($buffer));
         $connection->send($new_message, true);
         $connection->protocolData = array('binaryType' => self::BINARY_TYPE_BLOB);
         // 如果有设置onWebSocketConnect回调,尝试执行
         if (isset($connection->onWebSocketConnect)) {
             self::parseHttpHeader($buffer);
             try {
                 call_user_func($connection->onWebSocketConnect, $connection, $buffer);
             } catch (\Exception $e) {
                 echo $e;
             }
             $_GET = $_COOKIE = $_SERVER = array();
         }
         return 0;
     } elseif (0 === strpos($buffer, '<polic')) {
         if ('>' != $buffer[strlen($buffer) - 1]) {
             return 0;
         }
         $policy_xml = '<?xml version="1.0"?><cross-domain-policy><site-control permitted-cross-domain-policies="all"/><allow-access-from domain="*" to-ports="*"/></cross-domain-policy>' . "";
         $connection->send($policy_xml, true);
         $connection->consumeRecvBuffer(strlen($buffer));
         return 0;
     }
     // 出错
     $connection->close();
     return 0;
 }
Пример #3
0
 /**
  * 处理websocket握手
  * @param string $buffer
  * @param TcpConnection $connection
  * @return int
  */
 protected static function dealHandshake($buffer, $connection)
 {
     // 握手阶段客户端发送HTTP协议
     if (0 === strpos($buffer, 'GET')) {
         // 判断\r\n\r\n边界
         $heder_end_pos = strpos($buffer, "\r\n\r\n");
         if (!$heder_end_pos) {
             return 0;
         }
         // 解析Sec-WebSocket-Key
         $Sec_WebSocket_Key = '';
         if (preg_match("/Sec-WebSocket-Key: *(.*?)\r\n/", $buffer, $match)) {
             $Sec_WebSocket_Key = $match[1];
         } else {
             $connection->send("HTTP/1.1 400 Bad Request\r\n\r\n<b>400 Bad Request</b><br>Sec-WebSocket-Key not found", true);
             $connection->close();
             return 0;
         }
         // 握手的key
         $new_key = base64_encode(sha1($Sec_WebSocket_Key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));
         // 握手返回的数据
         $handshake_message = "HTTP/1.1 101 Switching Protocols\r\n";
         $handshake_message .= "Upgrade: websocket\r\n";
         $handshake_message .= "Sec-WebSocket-Version: 13\r\n";
         $handshake_message .= "Connection: Upgrade\r\n";
         $handshake_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";
         // 标记已经握手
         $connection->websocketHandshake = true;
         // 缓冲fin为0的包,直到fin为1
         $connection->websocketDataBuffer = '';
         // 当前数据帧的长度,可能是fin为0的帧,也可能是fin为1的帧
         $connection->websocketCurrentFrameLength = 0;
         // 当前帧的数据缓冲
         $connection->websocketCurrentFrameBuffer = '';
         // 消费掉握手数据,不触发onMessage
         $connection->consumeRecvBuffer(strlen($buffer));
         // 发送握手数据
         $connection->send($handshake_message, true);
         // 握手后有数据要发送
         if (!empty($connection->tmpWebsocketData)) {
             $connection->send($connection->tmpWebsocketData, true);
             $connection->tmpWebsocketData = '';
         }
         // blob or arraybuffer
         $connection->websocketType = self::BINARY_TYPE_BLOB;
         // 如果有设置onWebSocketConnect回调,尝试执行
         if (isset($connection->onWebSocketConnect)) {
             self::parseHttpHeader($buffer);
             try {
                 call_user_func($connection->onWebSocketConnect, $connection, $buffer);
             } catch (\Exception $e) {
                 echo $e;
             }
             $_GET = $_COOKIE = $_SERVER = array();
         }
         return 0;
     } elseif (0 === strpos($buffer, '<polic')) {
         $policy_xml = '<?xml version="1.0"?><cross-domain-policy><site-control permitted-cross-domain-policies="all"/><allow-access-from domain="*" to-ports="*"/></cross-domain-policy>' . "";
         $connection->send($policy_xml, true);
         $connection->consumeRecvBuffer(strlen($buffer));
         return 0;
     }
     // 出错
     $connection->send("HTTP/1.1 400 Bad Request\r\n\r\n<b>400 Bad Request</b><br>Invalid handshake data for websocket. ", true);
     $connection->close();
     return 0;
 }