This commit is contained in:
2020-11-10 14:33:55 +08:00
parent 9aac1c6540
commit 21a13001e9
+59 -13
View File
@@ -7,6 +7,8 @@ namespace HttpServer\Events;
use Exception;
use HttpServer\Abstracts\Callback;
use HttpServer\Route\Annotation\Websocket as AWebsocket;
use Snowflake\Event;
use Snowflake\Exception\ComponentException;
use Snowflake\Snowflake;
use Swoole\Http\Request as SRequest;
use Swoole\Http\Response as SResponse;
@@ -22,18 +24,17 @@ class OnHandshake extends Callback
/**
* @param SRequest $request
* @param SResponse $response
* @return bool|string
* @param $request
* @param $response
* @throws Exception
*/
public function onHandler(SRequest $request, SResponse $response)
private function resolveParse($request, $response)
{
/** @var Server $server */
$secWebSocketKey = $request->header['sec-websocket-key'];
$patten = '#^[+/0-9A-Za-z]{21}[AQgw]==$#';
if (0 === preg_match($patten, $secWebSocketKey) || 16 !== strlen(base64_decode($secWebSocketKey))) {
return false;
throw new Exception('protocol error.', 500);
}
$key = base64_encode(sha1(
$request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11',
@@ -51,16 +52,61 @@ class OnHandshake extends Callback
foreach ($headers as $key => $val) {
$response->header($key, $val);
}
}
/** @var AWebsocket $manager */
$manager = Snowflake::app()->annotation->get('websocket');
if ($manager->has($manager->getName(AWebsocket::HANDSHAKE))) {
$manager->runWith($manager->getName(AWebsocket::HANDSHAKE), [$request, $response]);
} else {
$response->status(502);
$response->end();
/**
* @param $response
* @param int $code
* @return false
*/
private function disconnect($response, $code = 500)
{
$response->status($code);
$response->end();
return false;
}
/**
* @param SRequest $request
* @param SResponse $response
* @return mixed|void
* @throws Exception
*/
public function onHandler(SRequest $request, SResponse $response)
{
try {
$this->resolveParse($request, $response);
/** @var AWebsocket $manager */
$manager = Snowflake::app()->annotation->get('websocket');
$name = $manager->getName(AWebsocket::HANDSHAKE);
if (!$manager->has($name)) {
return $this->disconnect($response);
}
return $manager->runWith($name, [$request, $response]);
} catch (\Throwable $exception) {
$this->addError($exception->getMessage());
return $this->disconnect($response, 500);
} finally {
$this->eventTrigger($request, $response);
}
return true;
}
/**
* @param $request
* @param $response
* @throws ComponentException
* @throws Exception
*/
private function eventTrigger($request, $response)
{
go(function () use ($request, $response) {
$manager = Snowflake::app()->getEvent();
$manager->trigger(Event::SERVER_HANDSHAKE, [$request, $response]);
});
}