I’m using Laravel in a project and I want to use broadcasting with laravel-echo-server and Redis. I have set up both in a docker container. Output below:
Redis
redis_1 | 1:C 27 Sep 06:24:35.521 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo redis_1 | 1:C 27 Sep 06:24:35.577 # Redis version=4.0.2, bits=64, commit=00000000, modified=0, pid=1, just started redis_1 | 1:C 27 Sep 06:24:35.577 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf redis_1 | 1:M 27 Sep 06:24:35.635 * Running mode=standalone, port=6379. redis_1 | 1:M 27 Sep 06:24:35.635 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. redis_1 | 1:M 27 Sep 06:24:35.635 # Server initialized redis_1 | 1:M 27 Sep 06:24:35.635 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. redis_1 | 1:M 27 Sep 06:24:35.636 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. redis_1 | 1:M 27 Sep 06:24:35.715 * DB loaded from disk: 0.079 seconds redis_1 | 1:M 27 Sep 06:24:35.715 * Ready to accept connections
A few warnings but nothing breaking.
laravel-echo-server
laravel-echo-server_1 | L A R A V E L E C H O S E R V E R laravel-echo-server_1 | laravel-echo-server_1 | version 1.3.1 laravel-echo-server_1 | laravel-echo-server_1 | ⚠ Starting server in DEV mode... laravel-echo-server_1 | laravel-echo-server_1 | ✔ Running at localhost on port 6001 laravel-echo-server_1 | ✔ Channels are ready. laravel-echo-server_1 | ✔ Listening for http events... laravel-echo-server_1 | ✔ Listening for redis events... laravel-echo-server_1 | laravel-echo-server_1 | Server ready! laravel-echo-server_1 | laravel-echo-server_1 | [6:29:38 AM] - dG0sLqG9Aa9oVVePAAAA joined channel: office-dashboard
The client seems to join the channel without any problems. However, if I kick of an event laravel-echo-server doesn’t receive the event.
I did a bit of research and found something about a queue worker. So I decided to run that (php artisan queue:work
) and see if that did anything. According to the docs it should run only the first task in the queue and then exit (as opposed to queue:listen
). And sure enough it began processing the event I kicked of earlier. But it didn’t stop and kept going until I killed it:
[2017-09-27 08:33:51] Processing: AppEventsCompanyUpdated [2017-09-27 08:33:51] Processing: AppEventsCompanyUpdated [2017-09-27 08:33:51] Processing: AppEventsCompanyUpdated [2017-09-27 08:33:51] Processing: AppEventsCompanyUpdated etc..
The following output showed in the redis container:
redis_1 | 1:M 27 Sep 06:39:01.562 * 10000 changes in 60 seconds. Saving... redis_1 | 1:M 27 Sep 06:39:01.562 * Background saving started by pid 19 redis_1 | 19:C 27 Sep 06:39:01.662 * DB saved on disk redis_1 | 19:C 27 Sep 06:39:01.663 * RDB: 2 MB of memory used by copy-on-write redis_1 | 1:M 27 Sep 06:39:01.762 * Background saving terminated with success
Now I either did so many api calls that the queue is so massive, or something is going wrong. Additionally, laravel-echo-server didn’t show any output after the jobs were ‘processed’.
I have created a hook in my Model which kicks of the event:
public function __construct(array $attributes = []) { parent::__construct($attributes); parent::created(function( $model ){ //event(new CompanyCreated($model)); }); parent::updated(function( $model ){ event(new CompanyUpdated($model)); }); parent::deleted(function( $model ){ event(new CompanyDeleted($model)); }); }
Then this is the event it kicks off:
class CompanyUpdated implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; /** * Create a new event instance. * * @return void */ public function __construct(Company $company) { $this->company = $company; } /** * Get the channels the event should broadcast on. * * @return Channel|array */ public function broadcastOn() { return new Channel('office-dashboard'); } }
And finally, this is the code on the front-end that’s listening for the event:
window.Echo.channel('office-dashboard') .listen('CompanyUpdated', (e) => { console.log(e.company.name); });
.env
file:
BROADCAST_DRIVER=redis CACHE_DRIVER=file SESSION_DRIVER=file QUEUE_DRIVER=redis REDIS_HOST=redis REDIS_PASSWORD=null REDIS_PORT=6379
Why isn’t the event passed to laravel-echo-server? Anything I’m missing or forgetting?
Advertisement
Answer
Started working out of the blue.