Skip to content
This repository has been archived by the owner on Feb 7, 2024. It is now read-only.

Installation with Lumen #11

Closed
timoschwarzer opened this issue Dec 5, 2018 · 12 comments
Closed

Installation with Lumen #11

timoschwarzer opened this issue Dec 5, 2018 · 12 comments

Comments

@timoschwarzer
Copy link

timoschwarzer commented Dec 5, 2018

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! :)

@timoschwarzer
Copy link
Author

Seems like it's not possible without big changes to the codebase.

@4levels
Copy link

4levels commented Dec 14, 2018

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);

@4levels
Copy link

4levels commented Dec 15, 2018

Hi @timoschwarzer, would you mind re-opening this issue as I'm sure the devs here will have a look.

@4levels
Copy link

4levels commented Dec 15, 2018

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.

@4levels
Copy link

4levels commented Dec 15, 2018

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) {
---            StatisticsLogger::save();
+++            app(StatisticsLogger::class)->save();
---        WebSocketsRouter::echo();
+++        app('websockets.router')->echo();
---        $routes = WebSocketsRouter::getRoutes();
+++        $routes = app('websockets.router')->getRoutes();

The same goes for the Authorize middleware
in Dashboard/Http/Middleware/Authorize.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) {

@4levels
Copy link

4levels commented Dec 15, 2018

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

@4levels
Copy link

4levels commented Dec 15, 2018

@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

@timoschwarzer timoschwarzer reopened this Dec 15, 2018
@4levels
Copy link

4levels commented Dec 17, 2018

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.

@mpociot
Copy link
Member

mpociot commented Dec 17, 2018

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.

@mpociot mpociot closed this as completed Dec 17, 2018
@kieuminhcanh
Copy link
Collaborator

kieuminhcanh commented Sep 25, 2019

#257
Try this solution

@lionslair lionslair mentioned this issue Aug 28, 2020
14 tasks
@Dasinfomedia2
Copy link

Dasinfomedia2 commented Nov 20, 2021

The above Solution works for lumen 8 as well. But after the pong call, the server crashed with the following error.Does any 1 has any idea about it?

In HttpStatisticsLogger.php line 82:

Call to undefined function BeyondCode\LaravelWebSockets\Statistics\Logger\action()

@Maijied
Copy link

Maijied commented Aug 9, 2022

attempted everything but I'm not sure where to move the vendor's src file.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants