8889841capp-providers.md000066600000006410150515675040007676 0ustar00# Custom App Providers With the multi-tenancy support of Laravel WebSockets, the default way of storing and retrieving the apps is by using the `websockets.php` config file. Depending on your setup, you might have your app configuration stored elsewhere and having to keep the configuration in sync with your app storage can be tedious. To simplify this, you can create your own `AppProvider` class that will take care of retrieving the WebSocket credentials for a specific WebSocket application. > Make sure that you do **not** perform any IO blocking tasks in your `AppProvider`, as they will interfere with the asynchronous WebSocket execution. In order to create your custom `AppProvider`, create a class that implements the `BeyondCode\LaravelWebSockets\AppProviders\AppProvider` interface. This is what it looks like: ```php interface AppProvider { /** @return array[BeyondCode\LaravelWebSockets\AppProviders\App] */ public function all(): array; /** @return BeyondCode\LaravelWebSockets\AppProviders\App */ public function findById($appId): ?App; /** @return BeyondCode\LaravelWebSockets\AppProviders\App */ public function findByKey(string $appKey): ?App; /** @return BeyondCode\LaravelWebSockets\AppProviders\App */ public function findBySecret(string $appSecret): ?App; } ``` The following is an example AppProvider that utilizes an Eloquent model: ```php namespace App\Providers; use App\Application; use BeyondCode\LaravelWebSockets\Apps\App; use BeyondCode\LaravelWebSockets\Apps\AppProvider; class MyCustomAppProvider implements AppProvider { public function all() : array { return Application::all() ->map(function($app) { return $this->instanciate($app->toArray()); }) ->toArray(); } public function findById($appId) : ? App { return $this->instanciate(Application::findById($appId)->toArray()); } public function findByKey(string $appKey) : ? App { return $this->instanciate(Application::findByKey($appKey)->toArray()); } public function findBySecret(string $appSecret) : ? App { return $this->instanciate(Application::findBySecret($appSecret)->toArray()); } protected function instanciate(?array $appAttributes) : ? App { if (!$appAttributes) { return null; } $app = new App( $appAttributes['id'], $appAttributes['key'], $appAttributes['secret'] ); if (isset($appAttributes['name'])) { $app->setName($appAttributes['name']); } if (isset($appAttributes['host'])) { $app->setHost($appAttributes['host']); } $app ->enableClientMessages($appAttributes['enable_client_messages']) ->enableStatistics($appAttributes['enable_statistics']); return $app; } } ``` Once you have implemented your own AppProvider, you need to set it in the `websockets.php` configuration file: ```php /** * This class is responsible for finding the apps. The default provider * will use the apps defined in this config file. * * You can create a custom provider by implementing the * `AppProvider` interface. */ 'app_provider' => MyCustomAppProvider::class, ``` _index.md000066600000000047150515675040006351 0ustar00--- title: Advanced Usage order: 4 --- custom-websocket-handlers.md000066600000004453150515675040012204 0ustar00# Custom WebSocket Handlers While this package's main purpose is to make the usage of either the Pusher JavaScript client or Laravel Echo as easy as possible, you are not limited to the Pusher protocol at all. There might be situations where all you need is a simple, bare-bone, WebSocket server where you want to have full control over the incoming payload and what you want to do with it - without having "channels" in the way. You can easily create your own custom WebSocketHandler class. All you need to do is implement Ratchets `Ratchet\WebSocket\MessageComponentInterface`. Once implemented, you will have a class that looks something like this: ```php namespace App; use Ratchet\ConnectionInterface; use Ratchet\RFC6455\Messaging\MessageInterface; use Ratchet\WebSocket\MessageComponentInterface; class MyCustomWebSocketHandler implements MessageComponentInterface { public function onOpen(ConnectionInterface $connection) { // TODO: Implement onOpen() method. } public function onClose(ConnectionInterface $connection) { // TODO: Implement onClose() method. } public function onError(ConnectionInterface $connection, \Exception $e) { // TODO: Implement onError() method. } public function onMessage(ConnectionInterface $connection, MessageInterface $msg) { // TODO: Implement onMessage() method. } } ``` In the class itself you have full control over all the lifecycle events of your WebSocket connections and can intercept the incoming messages and react to them. The only part missing is, that you will need to tell our WebSocket server to load this handler at a specific route endpoint. This can be achieved using the `WebSocketsRouter` facade. This class takes care of registering the routes with the actual webSocket server. You can use the `webSocket` method to define a custom WebSocket endpoint. The method needs two arguments: the path where the WebSocket handled should be available and the fully qualified classname of the WebSocket handler class. This could, for example, be done inside your `routes/web.php` file. ```php WebSocketsRouter::webSocket('/my-websocket', \App\MyCustomWebSocketHandler::class); ``` Once you've added the custom WebSocket route, be sure to restart our WebSocket server for the changes to take place.