Closed chimit closed 5 years ago
Try to read that, it could help: https://laracasts.com/discuss/channels/lumen/setting-up-event-broadcasting-for-lumen-app-using-log-driver-initially
I've seen that. The author told he didn't have any success with it: https://github.com/laravel/lumen-framework/issues/602#issuecomment-373957256
He says that:
I finally figured this out. It turns out that you shouldn't register BroadcastServiceProvider and configure broadcasting.php yourself in bootstrap/app.php. This is already done automatically in the Lumen source. Doing this yourself messes things up. Placing broadcasting.php in the config folder is all you need to do.
I find this quite confusing, as I've noticed that for other things (e.g. placing an auth.php in config or using MailServiceProvider) it is necessary to do the registering/configuring yourself in bootstrap/app.php. I wish the Lumen documentation would be a little more clear on this...
but I see that you did register BroadcastServiceProvider
Yes, I've already done this. This part works. Broadcasting in general works perfect. The problem is in auth routes for private channels. I don't know how to register them in Lumen.
May be related to issue #746
@chimit , i have the same issue , did you found any solution for this ?
A quick dirty hack is to overwrite the function it's trying to call in the service provider.
So in your class AppServiceProviderExample extends ServiceProvider
class, add:
//@TODO Remove me when a fix is implemented
public function loadRoutesFrom($location){
return $location;
}
It's trying to call the routesAreCached
function from Illuminate\Foundation\Application
but $this->app
is in Laravel\Lumen\Application
.
You can simply recreate the broadcasting/auth
route by yourself.
Create a BroadcastController.php
in Http\Controllers
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Broadcast;
class BroadcastController extends Controller {
public function authenticate(Request $request)
{
return Broadcast::auth($request);
}
}
Then, create a BroadcastServiceProvider.php
in Providers
and don't include Broadcast::routes()
this time.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class BroadcastServiceProvider extends ServiceProvider
{
public function boot()
{
require base_path('routes/channels.php');
}
}
Register your provider in bootstrap/app.php
.
$app->register(App\Providers\BroadcastServiceProvider::class);
Create a channels.php
in routes
and define your authentication rules for your private channels as usual.
<?php
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('order.{orderId}', function ($user, $orderId) {
return $user->id === Order::findOrNew($orderId)->user_id;
});
In routes/web.php
, simply recreate the broadcasting/auth
route.
$app->group(['middleware' => 'auth'], function () use ($app) {
$app->post('broadcasting/auth', ['uses' => 'BroadcastController@authenticate']);
});
Also, don't forget to config your broadcast and queue drivers as mentioned in document.
The routesAreCached
issue should be resolved in 5.7
@driesvints the problem was not solved. In Lumen 5.7 auth routes don't work as well:
[2018-10-22 08:07:17] local.ERROR: Symfony\Component\Debug\Exception\FatalThrowableError: Call to undefined method Laravel\Lumen\Routing\Router::match() in /home/vagrant/code/project/vendor/illuminate/broadcasting/BroadcastManager.php:68
Stack trace:
#0 [internal function]: Illuminate\Broadcasting\BroadcastManager->Illuminate\Broadcasting\{closure}(Object(Laravel\Lumen\Routing\Router))
#1 /home/vagrant/code/project/vendor/laravel/lumen-framework/src/Routing/Router.php(62): call_user_func(Object(Closure), Object(Laravel\Lumen\Routing\Router))
#2 /home/vagrant/code/project/vendor/illuminate/broadcasting/BroadcastManager.php(72): Laravel\Lumen\Routing\Router->group(Array, Object(Closure))
#3 /home/vagrant/code/project/vendor/illuminate/support/Facades/Facade.php(223): Illuminate\Broadcasting\BroadcastManager->routes()
#4 /home/vagrant/code/project/app/Providers/BroadcastServiceProvider.php(17): Illuminate\Support\Facades\Facade::__callStatic('routes', Array)
#5 [internal function]: App\Providers\BroadcastServiceProvider->boot()
#6 /home/vagrant/code/project/vendor/illuminate/container/BoundMethod.php(29): call_user_func_array(Array, Array)
#7 /home/vagrant/code/project/vendor/illuminate/container/BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#8 /home/vagrant/code/project/vendor/illuminate/container/BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Object(Laravel\Lumen\Application), Array, Object(Closure))
#9 /home/vagrant/code/project/vendor/illuminate/container/Container.php(572): Illuminate\Container\BoundMethod::call(Object(Laravel\Lumen\Application), Array, Array, NULL)
#10 /home/vagrant/code/project/vendor/laravel/lumen-framework/src/Application.php(237): Illuminate\Container\Container->call(Array)
#11 /home/vagrant/code/project/vendor/laravel/lumen-framework/src/Application.php(222): Laravel\Lumen\Application->bootProvider(Object(App\Providers\BroadcastServiceProvider))
#12 [internal function]: Laravel\Lumen\Application->Laravel\Lumen\{closure}(Object(App\Providers\BroadcastServiceProvider), 'App\\Providers\\B...')
#13 /home/vagrant/code/project/vendor/laravel/lumen-framework/src/Application.php(223): array_walk(Array, Object(Closure))
#14 /home/vagrant/code/project/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php(159): Laravel\Lumen\Application->boot()
#15 /home/vagrant/code/project/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php(108): Laravel\Lumen\Application->dispatch(NULL)
#16 /home/vagrant/code/project/public/index.php(28): Laravel\Lumen\Application->run()
#17 {main} {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Call to undefined method Laravel\\Lumen\\Routing\\Router::match() at /home/vagrant/code/project/vendor/illuminate/broadcasting/BroadcastManager.php:68)
[stacktrace]
#0 [internal function]: Illuminate\\Broadcasting\\BroadcastManager->Illuminate\\Broadcasting\\{closure}(Object(Laravel\\Lumen\\Routing\\Router))
#1 /home/vagrant/code/project/vendor/laravel/lumen-framework/src/Routing/Router.php(62): call_user_func(Object(Closure), Object(Laravel\\Lumen\\Routing\\Router))
#2 /home/vagrant/code/project/vendor/illuminate/broadcasting/BroadcastManager.php(72): Laravel\\Lumen\\Routing\\Router->group(Array, Object(Closure))
#3 /home/vagrant/code/project/vendor/illuminate/support/Facades/Facade.php(223): Illuminate\\Broadcasting\\BroadcastManager->routes()
#4 /home/vagrant/code/project/app/Providers/BroadcastServiceProvider.php(17): Illuminate\\Support\\Facades\\Facade::__callStatic('routes', Array)
#5 [internal function]: App\\Providers\\BroadcastServiceProvider->boot()
#6 /home/vagrant/code/project/vendor/illuminate/container/BoundMethod.php(29): call_user_func_array(Array, Array)
#7 /home/vagrant/code/project/vendor/illuminate/container/BoundMethod.php(87): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#8 /home/vagrant/code/project/vendor/illuminate/container/BoundMethod.php(31): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Laravel\\Lumen\\Application), Array, Object(Closure))
#9 /home/vagrant/code/project/vendor/illuminate/container/Container.php(572): Illuminate\\Container\\BoundMethod::call(Object(Laravel\\Lumen\\Application), Array, Array, NULL)
#10 /home/vagrant/code/project/vendor/laravel/lumen-framework/src/Application.php(237): Illuminate\\Container\\Container->call(Array)
#11 /home/vagrant/code/project/vendor/laravel/lumen-framework/src/Application.php(222): Laravel\\Lumen\\Application->bootProvider(Object(App\\Providers\\BroadcastServiceProvider))
#12 [internal function]: Laravel\\Lumen\\Application->Laravel\\Lumen\\{closure}(Object(App\\Providers\\BroadcastServiceProvider), 'App\\\\Providers\\\\B...')
#13 /home/vagrant/code/project/vendor/laravel/lumen-framework/src/Application.php(223): array_walk(Array, Object(Closure))
#14 /home/vagrant/code/project/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php(159): Laravel\\Lumen\\Application->boot()
#15 /home/vagrant/code/project/vendor/laravel/lumen-framework/src/Concerns/RoutesRequests.php(108): Laravel\\Lumen\\Application->dispatch(NULL)
#16 /home/vagrant/code/project/public/index.php(28): Laravel\\Lumen\\Application->run()
#17 {main}
"}
@driesvints Can we reopen this issue? I can reproduce this.
Done
@driesvints @chimit Instead of copying the app\Providers\BroadcastServiceProvider.php
file from Laravel, you should register the routes yourself in Lumen. The Broadcast::routes();
method calls certain methods which are incompatible with Lumen. However, this method is more of a helper than a necessity, since you can just manually register the routes.
Therefore, we can assume that this feature works as expected and is not necessarily a bug, but it just requires a little more configuration.
Okay, gonna close this then again.
I've been working with lumen for a year and more. I hadn't had to enable the facades until now. Why? Because the Broadcasting module is not designed to function without them. Broadcast::routes() leads to
So I stopped relying on the routes method and registered the routes manually in my routes.php file(very nasty hack)
$router->get('/broadcasting/auth', '\\'.BroadcastController::class.'@authenticate');
$router->post('/broadcasting/auth', '\\'.BroadcastController::class.'@authenticate');
But then if I disable the facades, at the moment of the authentication I get an error about
and if I enable them everything works as expected. I tracked the error down to the Illuminate\Broadcasting\BroadcastController
class
class BroadcastController extends Controller
{
/**
* Authenticate the request for channel access.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function authenticate(Request $request)
{
if ($request->hasSession()) {
$request->session()->reflash();
}
return Broadcast::auth($request);
}
}
which is relying on the Broadcast facade and then is when it fails to handle the call. If I edit the controller to
namespace Illuminate\Broadcasting;
use Illuminate\Contracts\Broadcasting\Broadcaster;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Broadcast;
class BroadcastController extends Controller
{
/**
* Authenticate the request for channel access.
*
* @param \Illuminate\Http\Request $request
* @param Illuminate\Contracts\Broadcasting\Broadcaster $broadcaster
* @return \Illuminate\Http\Response
*/
public function authenticate(Request $request, Broadcaster $broadcaster)
{
if ($request->hasSession()) {
$request->session()->reflash();
}
return $broadcaster->auth($request);
}
}
and my channels.php to
$broadcast = app(Illuminate\Contracts\Broadcasting\Broadcaster::class);
$broadcast->channel('channel', .....)
then I'm back on business... I don't think this is a bug, but a oversight about the controller and channels depending directly on the Facades. I guess for Laravel is no problem, but for lumen there's some of us out there that don't like the Facades and we try to not enable them.
Oh, and btw I'm using lumen 5.7, but I checked on the 5.8 branch if the controller changed and is still the same, so I think the error is still there.
For now I'm going to implement my own Controller to avoid using the one that depends on the Facades, but I think this is easily fixable.
Cheers! Martin
@knifesk it's best that you just upgrade to the Laravel framework if you want to use broadcasting.
@driesvints thanks for the reply! I'm using broadcasting with redis and a separate app that uses laravel-echo-server to handle the Socket.io connections. The front-end is an entire separated Vue project that is being develop by another team. This is a REST API and it doesn't rely on sessions. Also we're using Auth0 for the authentication with JWTs.
Why do you recommend using Laravel? Lumen is doing just fine for me, the only issue is that I have the Facades disabled and I bumped into this issue. Lumen could support Broadcasting and Notifications just fine if the module weren't designed with facades enabled in mind. Or is there any other reason that I'm not aware of?
We don't support using the broadcast module with Lumen.
Ohh I see... That explains why I had such a hard time making it work and the documentation of Lumen said nothing about it haahah. Well, I'm happy with what I achieved. I guess that in the future I could migrate to Laravel if the need arises. For now I'll stick to Lumen because deadlines are pretty close haha.
Thank you!
On Tue, Jul 9, 2019 at 11:24 AM Dries Vints notifications@github.com wrote:
We don't support using the broadcast module with Lumen.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/laravel/lumen-framework/issues/744?email_source=notifications&email_token=AACRO3DBA7BIHYJODGBC733P6SNSHA5CNFSM4EV3CJ32YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZQNW3A#issuecomment-509664108, or mute the thread https://github.com/notifications/unsubscribe-auth/AACRO3D6HVNY7OKEZQK4DV3P6SNSHANCNFSM4EV3CJ3Q .
is it supported now?
I wish I knew lumen doesn't support broadcasting before using it, right now am really stuck.
If you need broadcasting please use Laravel.
Description:
I'm trying to use broadcasting in Lumen. Everything works fine except private channels. I can't setup auth routes.
Got an error:
Steps To Reproduce:
I copied a
app\Providers\BroadcastServiceProvider.php
file from Laravel and put it into the same place in Lumen and added:into the
bootstrap\app.php
.Apparently, it's because of different routes packages in Laravel and Lumen. So how to bypass this problem?