Skip to content

Commit

Permalink
Update Websocket.php
Browse files Browse the repository at this point in the history
  • Loading branch information
localzet committed Aug 21, 2024
1 parent 4b2fbaa commit 6bce0c3
Showing 1 changed file with 68 additions and 77 deletions.
145 changes: 68 additions & 77 deletions src/Server/Protocols/Websocket.php
Original file line number Diff line number Diff line change
Expand Up @@ -317,103 +317,94 @@ public static function dealHandshake(string $buffer, TcpConnection $connection):
$request->connection = $connection;
$connection->request = $request;

try {
// Протокол HTTP.
if ($request->isMethod('GET')) {
$headerEndPos = strpos($buffer, "\r\n\r\n");
if (!$headerEndPos) {
return 0;
}
$headerLength = $headerEndPos + 4;

// Get Sec-WebSocket-Key.
$SecWebSocketKey = $request->header('Sec-WebSocket-Key');
if (!$SecWebSocketKey) {
$connection->close(format_http_response(400), true);
return 0;
}
// Протокол HTTP.
if ($request->isMethod('GET')) {
$headerEndPos = strpos($buffer, "\r\n\r\n");
if (!$headerEndPos) {
return 0;
}
$headerLength = $headerEndPos + 4;

// Данные ответа на рукопожатие.
$connection->response = new Server\Protocols\Http\Response(101, [
'Sec-WebSocket-Accept' => base64_encode(sha1($SecWebSocketKey . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true)),
'Connection' => 'Upgrade',
'Upgrade' => 'websocket',
'Sec-WebSocket-Version' => 13,
], null);
// Get Sec-WebSocket-Key.
$SecWebSocketKey = $request->header('Sec-WebSocket-Key');
if (!$SecWebSocketKey) {
$connection->close(format_http_response(400), true);
return 0;
}

// Буфер данных websocket.
$connection->context->websocketDataBuffer = '';
// Данные ответа на рукопожатие.
$connection->response = new Server\Protocols\Http\Response(101, [
'Sec-WebSocket-Accept' => base64_encode(sha1($SecWebSocketKey . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true)),
'Connection' => 'Upgrade',
'Upgrade' => 'websocket',
'Sec-WebSocket-Version' => 13,
], null);

// Текущая длина кадра websocket.
$connection->context->websocketCurrentFrameLength = 0;
// Буфер данных websocket.
$connection->context->websocketDataBuffer = '';

// Текущие данные кадра websocket.
$connection->context->websocketCurrentFrameBuffer = '';
// Текущая длина кадра websocket.
$connection->context->websocketCurrentFrameLength = 0;

// Разбор данных рукопожатия.
$connection->consumeRecvBuffer($headerLength);
// Текущие данные кадра websocket.
$connection->context->websocketCurrentFrameBuffer = '';

// Попытка вызвать обратный вызов onWebSocketConnect.
$onWebSocketConnect = $connection->onWebSocketConnect ?? $connection->server->onWebSocketConnect ?? false;
if ($onWebSocketConnect) {
try {
$addResponse = $onWebSocketConnect($connection, $request) ?? null;
// Разбор данных рукопожатия.
$connection->consumeRecvBuffer($headerLength);

if ($addResponse instanceof Server\Protocols\Http\Response) {
if ($addResponse->getHeaders()) {
$connection->response->withHeaders($addResponse->getHeaders());
}
// Попытка вызвать обратный вызов onWebSocketConnect.
$onWebSocketConnect = $connection->onWebSocketConnect ?? $connection->server->onWebSocketConnect ?? false;
if ($onWebSocketConnect) {
try {
$addResponse = $onWebSocketConnect($connection, $request) ?? null;

if ($addResponse->getStatusCode() >= 400) {
$connection->response->withStatus($addResponse->getStatusCode());
if ($addResponse instanceof Server\Protocols\Http\Response) {
if ($addResponse->getHeaders()) {
$connection->response->withHeaders($addResponse->getHeaders());
}

if (!empty($addResponse->rawBody())) {
$connection->response->withBody($addResponse->rawBody());
}
if ($addResponse->getStatusCode() >= 400) {
$connection->response->withStatus($addResponse->getStatusCode());

$connection->close((string)$connection->response, true);
return 0;
if (!empty($addResponse->rawBody())) {
$connection->response->withBody($addResponse->rawBody());
}

$connection->close((string)$connection->response, true);
return 0;
}
} catch (Throwable $e) {
Server::stopAll(250, $e);
}
} catch (Throwable $e) {
Server::stopAll(250, $e);
}
}

// blob или arraybuffer
if (empty($connection->websocketType)) {
$connection->websocketType = static::BINARY_TYPE_BLOB;
}
// blob или arraybuffer
if (empty($connection->websocketType)) {
$connection->websocketType = static::BINARY_TYPE_BLOB;
}

if ($connection->headers) {
$connection->response->withHeaders($connection->headers);
}
if ($connection->headers) {
$connection->response->withHeaders($connection->headers);
}

// Отправить ответ на рукопожатие.
$connection->send((string)$connection->response, true);
// Пометить рукопожатие как завершенное.
$connection->context->websocketHandshake = true;

// Есть данные, ожидающие отправки.
if (!empty($connection->context->tmpWebsocketData)) {
// Отправка временных данных websocket.
$connection->send($connection->context->tmpWebsocketData, true);
// Очистка временных данных websocket.
$connection->context->tmpWebsocketData = '';
}
// Отправить ответ на рукопожатие.
$connection->send((string)$connection->response, true);
// Пометить рукопожатие как завершенное.
$connection->context->websocketHandshake = true;

if (strlen($buffer) > $headerLength) {
return static::input(substr($buffer, $headerLength), $connection);
}
return 0;
// Есть данные, ожидающие отправки.
if (!empty($connection->context->tmpWebsocketData)) {
// Отправка временных данных websocket.
$connection->send($connection->context->tmpWebsocketData, true);
// Очистка временных данных websocket.
$connection->context->tmpWebsocketData = '';
}
} finally {
if (isset($connection->request)) {
// Удаляем ссылки на запрос и соединение для предотвращения утечки памяти.
$request = $connection->request;
// Очищаем свойства запроса и соединения.
$request->session = $request->connection = $connection->request = null;

if (strlen($buffer) > $headerLength) {
return static::input(substr($buffer, $headerLength), $connection);
}
return 0;
}

// Неверный запрос рукопожатия через веб-сокет.
Expand Down

0 comments on commit 6bce0c3

Please sign in to comment.