I'll try to figure out how to install and use laravel-websockets with Lumen and come back here when I have a working setup.
Tips and hints appreciated! :)
Seems like it's not possible without big changes to the codebase.
Hi @timoschwarzer,
I did get it running but with indeed some adjustments and limitations. The Dashboard is not 100% functional but what matters most (to me) is that the websocket connections are working and can be used for broadcasting to from within my Lumen app, as well as handle messages from clients.
I lost all my config due to a regrettable git reset --hard, but I'll try to get it up and running again. I'll keep adding messages here..
I'm now keeping my changes in my fork over here:
https://github.com/4levels/laravel-websockets/tree/feat/lumen-compatibility in the feat/lumen-compatibility branch
The first hurdle is the routing config which is not compatible with Lumen.
I changed the following in WebSocketsServiceProvider::registerRoutes():
app('router')->group(['prefix' => config('websockets.path', '')], function () {
app('router')->get('/', ShowDashboard::class);
app('router')->get('/api/{appId}/statistics', DashboardApiController::class . '@getStatistics');
app('router')->get('/api/{appId}/statistics', DashboardApiController::class . '@getStatistics');
app('router')->post('auth', AuthenticateDashboard::class);
app('router')->post('event', SendMessage::class);
app('router')->group(['middleware' => AuthorizeStatistics::class], function () {
app('router')->post('statistics', [
'as' => 'statistics',
'uses' => WebSocketStatisticsEntriesController::class . '@store']);
});
});
I've seen nice approaches where the above section of routes is separated in a different file. A check then loads the file 'as is' for Lumen or parses it the Laravel way, something like (where $path is the routes file):
if (Str::contains($this->app->version(), 'Lumen')) {
require realpath($path);
return;
}
parent::loadRoutesFrom($path);
Hi @timoschwarzer, would you mind re-opening this issue as I'm sure the devs here will have a look.
Second hurdle I had to overcome:
use of request() and csrf_token() in blade templates is not working in Lumen. For now I simply replaced the calls with a static string where-ever needed just to test the dashboard:
in resources/views/dashboard.blade.php:
--- authEndpoint: '/{{ request()->path() }}/auth',
+++ authEndpoint: '/laravel-websockets/auth',
and
--- 'X-CSRF-Token': "{{ csrf_token() }}"
+++ 'X-CSRF-Token': this.app.key
This is not a long term solution but since I honestly couldn't care less about the dashboard, this is just a proof of concept.
Third change: I'm not a fan of Facades and I strongly believe that any Laravel library that wants to be a true library should never force users to enable facades. Facade's are optional and library's should be written without them. That being said, this is how I addressed this in the websocket:serve console command
in Console/StartWebSocketServer.php
--- use BeyondCode\LaravelWebSockets\Facades\StatisticsLogger;
--- use BeyondCode\LaravelWebSockets\Facades\WebSocketsRouter;
--- use BeyondCode\LaravelWebSockets\Statistics\Logger\StatisticsLogger as StatisticsLoggerInterface;
--- use BeyondCode\LaravelWebSockets\Facades\StatisticsLogger;
--- use BeyondCode\LaravelWebSockets\Facades\WebSocketsRouter;
+++ use BeyondCode\LaravelWebSockets\Statistics\Logger\StatisticsLogger;
Next I changed the invocations:
--- app()->singleton(StatisticsLoggerInterface::class, function () use ($browser) {
+++ app()->singleton(StatisticsLogger::class, function () use ($browser) {
```php
--- StatisticsLogger::save();
+++ app(StatisticsLogger::class)->save();
```php
--- WebSocketsRouter::echo();
+++ app('websockets.router')->echo();
```php
--- $routes = WebSocketsRouter::getRoutes();
+++ $routes = app('websockets.router')->getRoutes();
The same goes for the Authorize middleware
in `Dashboard/Http/Middleware/Authorize.php`
```php
--- use Illuminate\Support\Facades\Gate;
+++ use Illuminate\Contracts\Auth\Access\Gate;
--- return Gate::check('viewWebSocketsDashboard') ? $next($request) : abort(403);
+++ return app(Gate::class)->check('viewWebSocketsDashboard') ? $next($request) : abort(403);
And in the service provider (besides changing the routes as explained before):
in WebSocketsServiceProvider.php
--- use Illuminate\Support\Facades\Gate;
--- use Illuminate\Support\Facades\Route;
+++ use Illuminate\Contracts\Auth\Access\Gate;
and it's registerDashboardGate function:
--- Gate::define('viewWebSocketsDashboard', function ($user = null) {
+++ app(Gate::class)->define('viewWebSocketsDashboard', function ($user = null) {
There are still some issues in the controllers I'm currently investigating.
The reason is that the Lumen Request class has no validate method. I'm still checking for a cleaner solution. Currently I "fixed" it (braking Laravel support in the process?) as below:
in Statistics/Https/Controllers/WebSocketStatisticsEntriesController.php:
+++ use Laravel\Lumen\Routing\Controller as BaseController;
--- class WebSocketStatisticsEntriesController
+++ class WebSocketStatisticsEntriesController extends BaseController
--- $validatedAttributes = $request->validate([
+++ $validatedAttributes = $this->validate($request, [
I then applied the same changes to Dashboard/Http/Controllers/SendMessage.php
@timoschwarzer in case you missed the edit of my first message, I'm now keeping things organized in a separate branch in my fork:
https://github.com/4levels/laravel-websockets/tree/feat/lumen-compatibility
Hi @timoschwarzer,
I've lost my fate in the people behind this project so I have very little hope of them ever being able to make this work with Lumen. For starters, both freekmurze and mpociot deny the importance of being able to add this to a project without facades enabled.. I don't understand why so many Laravel developers are acting like facade junkies! I bet somewhere in the near future they will remove the facade dependency themselves, pretending this never even happened (I've seen this happen before).
On top of that, they closed both my issue and PR for no good reason, claiming that "nobody reported issues" (I did) and the use of facades is fine.
I'll be creating my own version of this package and keep you posted.. Very disappointed at the moment.
This package is simply not intended to be used with Lumen and we do not plan on maintaining the required modifications for this. Feel free to fork the repository.
https://github.com/beyondcode/laravel-websockets/pull/257
Try this solution
Most helpful comment
Hi @timoschwarzer,
I did get it running but with indeed some adjustments and limitations. The Dashboard is not 100% functional but what matters most (to me) is that the websocket connections are working and can be used for broadcasting to from within my Lumen app, as well as handle messages from clients.
I lost all my config due to a regrettable git reset --hard, but I'll try to get it up and running again. I'll keep adding messages here..
I'm now keeping my changes in my fork over here:
https://github.com/4levels/laravel-websockets/tree/feat/lumen-compatibility in the
feat/lumen-compatibilitybranchThe first hurdle is the routing config which is not compatible with Lumen.
I changed the following in WebSocketsServiceProvider::registerRoutes():
I've seen nice approaches where the above section of routes is separated in a different file. A check then loads the file 'as is' for Lumen or parses it the Laravel way, something like (where $path is the routes file):