diff --git a/src/Console/StartWebSocketServer.php b/src/Console/StartWebSocketServer.php index ac112be..c078fc5 100644 --- a/src/Console/StartWebSocketServer.php +++ b/src/Console/StartWebSocketServer.php @@ -4,7 +4,8 @@ namespace BeyondCode\LaravelWebSockets\Console; use BeyondCode\LaravelWebSockets\Facades\WebSocketRouter; use BeyondCode\LaravelWebSockets\Server\Logger\ConnectionLogger; -use BeyondCode\LaravelWebSockets\Server\Logger\MessageLogger; +use BeyondCode\LaravelWebSockets\Server\Logger\HttpLogger; +use BeyondCode\LaravelWebSockets\Server\Logger\WebsocketLogger; use Illuminate\Console\Command; use BeyondCode\LaravelWebSockets\Server\WebSocketServer; @@ -19,16 +20,28 @@ class StartWebSocketServer extends Command public function handle() { $this + ->configureHttpLogger() ->configureMessageLogger() ->configureConnectionLogger() ->registerEchoRoutes() ->startWebSocketServer(); } + protected function configureHttpLogger() + { + app()->singleton(HttpLogger::class, function() { + return (new HttpLogger($this->output)) + ->enable(config('app.debug')) + ->verbose($this->output->isVerbose()); + }); + + return $this; + } + protected function configureMessageLogger() { - app()->singleton(MessageLogger::class, function() { - return (new MessageLogger($this->output)) + app()->singleton(WebsocketLogger::class, function() { + return (new WebsocketLogger($this->output)) ->enable(config('app.debug')) ->verbose($this->output->isVerbose()); }); diff --git a/src/Server/Logger/HttpLogger.php b/src/Server/Logger/HttpLogger.php new file mode 100644 index 0000000..7058bad --- /dev/null +++ b/src/Server/Logger/HttpLogger.php @@ -0,0 +1,58 @@ +setApp($app); + } + + public function setApp(MessageComponentInterface $app) + { + $this->app = $app; + + return $this; + } + + public function onOpen(ConnectionInterface $connection) + { + $this->app->onOpen($connection); + } + + public function onMessage(ConnectionInterface $connection, $message) + { + $this->app->onMessage($connection, $message); + } + + public function onClose(ConnectionInterface $connection) + { + $this->app->onClose($connection); + } + + public function onError(ConnectionInterface $connection, Exception $exception) + { + $exceptionClass = get_class($exception); + + $message = "Exception `{$exceptionClass}` thrown: `{$exception->getMessage()}`"; + + if ($this->verbose) { + $message .= $exception->getTraceAsString(); + } + + $this->error($message); + + $this->app->onError($connection, $exception); + } + +} \ No newline at end of file diff --git a/src/Server/Logger/Logger.php b/src/Server/Logger/Logger.php index a8ee9fa..756c35e 100644 --- a/src/Server/Logger/Logger.php +++ b/src/Server/Logger/Logger.php @@ -18,7 +18,7 @@ class Logger public static function isEnabled(): bool { - return app(MessageLogger::class)->enabled; + return app(WebsocketLogger::class)->enabled; } public function __construct(OutputInterface $consoleOutput) diff --git a/src/Server/Logger/MessageLogger.php b/src/Server/Logger/WebsocketLogger.php similarity index 88% rename from src/Server/Logger/MessageLogger.php rename to src/Server/Logger/WebsocketLogger.php index f1c833c..4a8f0ed 100644 --- a/src/Server/Logger/MessageLogger.php +++ b/src/Server/Logger/WebsocketLogger.php @@ -8,14 +8,14 @@ use Ratchet\ConnectionInterface; use Ratchet\RFC6455\Messaging\MessageInterface; use Ratchet\WebSocket\MessageComponentInterface; -class MessageLogger extends Logger implements MessageComponentInterface +class WebsocketLogger extends Logger implements MessageComponentInterface { /** @var \Ratchet\Http\HttpServerInterface */ protected $app; - public static function decorate(MessageComponentInterface $app): MessageLogger + public static function decorate(MessageComponentInterface $app): WebsocketLogger { - $logger = app(MessageLogger::class); + $logger = app(WebsocketLogger::class); return $logger->setApp($app); } @@ -45,7 +45,7 @@ class MessageLogger extends Logger implements MessageComponentInterface public function onClose(ConnectionInterface $connection) { - $this->warn("{$connection->client->appId}: connection id {$connection->socketId} closed."); + $this->warn("{optional($connection->client)->appId}: connection id {$connection->socketId} closed."); $this->app->onClose(ConnectionLogger::decorate($connection)); } diff --git a/src/Server/Router.php b/src/Server/Router.php index 41a7bc8..34c73a3 100644 --- a/src/Server/Router.php +++ b/src/Server/Router.php @@ -2,7 +2,7 @@ namespace BeyondCode\LaravelWebSockets\Server; -use BeyondCode\LaravelWebSockets\Server\Logger\MessageLogger; +use BeyondCode\LaravelWebSockets\Server\Logger\WebsocketLogger; use BeyondCode\LaravelWebSockets\HttpApi\Controllers\FetchChannel; use BeyondCode\LaravelWebSockets\HttpApi\Controllers\FetchChannels; use BeyondCode\LaravelWebSockets\HttpApi\Controllers\FetchUsers; @@ -89,8 +89,8 @@ class Router if (is_subclass_of($action, MessageComponentInterface::class)) { $app = app($action); - if (MessageLogger::isEnabled()) { - $app = MessageLogger::decorate($app); + if (WebsocketLogger::isEnabled()) { + $app = WebsocketLogger::decorate($app); } return new WsServer($app); diff --git a/src/Server/WebSocketServer.php b/src/Server/WebSocketServer.php new file mode 100644 index 0000000..b392112 --- /dev/null +++ b/src/Server/WebSocketServer.php @@ -0,0 +1,98 @@ +loop = LoopFactory::create(); + + $this->routes = $routes; + } + + public function setHost(string $host) + { + $this->host = $host; + + return $this; + } + + public function setPort(string $port) + { + $this->port = $port; + + return $this; + } + + public function setLoop(LoopInterface $loop) + { + $this->loop = $loop; + + return $this; + } + + public function setConsoleOutput(OutputInterface $consoleOutput) + { + $this->consoleOutput = $consoleOutput; + + return $this; + } + + public function run() + { + $server = $this->createServer(); + + $server->run(); + } + + protected function createServer(): IoServer + { + $socket = new Server("{$this->host}:{$this->port}", $this->loop); + + if (config('websockets.ssl.local_cert')) { + $socket = new SecureServer($socket, $this->loop, config('websockets.ssl')); + } + + $urlMatcher = new UrlMatcher($this->routes, new RequestContext); + + $router = new Router($urlMatcher); + + $app = new OriginCheck($router, config('websockets.allowedOrigins', [])); + + $httpServer = new HttpServer($app, config('websockets.maxRequestSize')); + + if (HttpLogger::isEnabled()) { + $httpServer = HttpLogger::decorate($httpServer); + } + + return new IoServer($httpServer, $socket, $this->loop); + } +}