Hello there!
I want to trigger an event when a user's feed (of articles) is being updated. When the feed is updated, a FeedGenerated
event is being broadcasted, and I would like my front-end to catch the event to allow user to manually refresh his feed.
The FeedGenerated
event is being listened by the UpdateFeedArticles
listener. This listener just Logs something for now (and it logs successfully).
The event is broadcasted as follow:
FeedGenerated::broadcast($user);
The FeedGenerated
event:
<?php
namespace App\Providers;
use App\Models\User;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithBroadcasting;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class FeedGenerated implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels, InteractsWithBroadcasting;
/**
* The name of the queue connection to use when broadcasting the event.
*
* @var string
*/
public string $connection = 'redis';
/**
* The name of the queue on which to place the broadcasting job.
*
* @var string
*/
public string $queue = 'default';
/**
* Create a new event instance.
*/
public function __construct(public User $user)
{
//
}
/**
* Get the channels the event should broadcast on.
*
* @return array<int, \Illuminate\Broadcasting\Channel>
*/
public function broadcastOn(): array
{
return [
new Channel("user"),
];
}
}
The UpdateFeedArticle
listener:
<?php
namespace App\Providers;
use App\Providers\FeedGenerated;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class UpdateFeedArticles
{
/**
* Create the event listener.
*/
public function __construct()
{
//
}
/**
* Handle the event.
*/
public function handle(FeedGenerated $event): void
{
\Log::debug('Event triggered', ['event' => $event, 'listener' => $this]);
}
}
Laravel Echo instanciation:
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Websocket = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
wsHost: import.meta.env.VITE_PUSHER_HOST,
wsPort: import.meta.env.VITE_PUSHER_PORT,
wssPort: import.meta.env.VITE_PUSHER_PORT,
forceTLS: false,
encrypted: false,
disableStats: true,
enabledTransports: ['ws', 'wss'],
});
Websocket.connector.pusher.connection.bind('connected', () => {
console.log('✅ Soketi Connected!');
});
Websocket.connector.pusher.connection.bind('disconnected', () => {
console.log('👋 Soketi Disconnected!');
});
Websocket.connector.pusher.connection.bind('failed', () => {
console.log('❌ Soketi Connection Failed!');
});
Here is my docker-composer.yml
version: '3'
networks:
network_shapes:
ipam:
driver: default
driver: bridge
services:
phpfpm:
container_name: '${APP_NAME}'
build:
args:
user: '${WWWUSER}'
uid: '${WWWGROUP}'
context: ./docker
dockerfile: Dockerfile
working_dir: /var/www/html
volumes:
- ./:/var/www/html
- 'tmpfiles:/tmp'
networks:
- network_shapes
depends_on:
- mariadb
restart: unless-stopped
soketi:
image: 'quay.io/soketi/soketi:latest-16-alpine'
environment:
SOKETI_DEBUG: '${SOKETI_DEBUG:-1}'
SOKETI_METRICS_SERVER_PORT: '${SOKETI_METRICS_SERVER_PORT}'
ports:
- '${SOKETI_PORT:-6001}:6001'
- '${SOKETI_METRICS_SERVER_PORT:-9601}:9601'
networks:
- network_shapes
depends_on:
- redis
nginx:
image: ${NGINX_IMAGE}
networks:
- network_shapes
ports:
- '127.0.0.1:${APP_PORT}:80'
volumes:
- ./docker/nginx/tkt.conf:/etc/nginx/conf.d/default.conf
- ./:/var/www/html
- 'tmpfiles:/tmp'
links:
- phpfpm
depends_on:
- mariadb
restart: unless-stopped
mongo:
...
redis:
image: 'redis:latest'
ports:
- '127.0.0.1:${REDIS_PORT:-6379}:6379'
volumes:
- 'redis_volume:/data'
networks:
- network_shapes
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
retries: 3
timeout: 5s
restart: unless-stopped
mariadb:
...
mailhog:
...
volumes:
tmpfiles:
driver: local
mariadb_volume:
driver: local
redis_volume:
driver: local
Here is my Nginx tkt.conf
server {
listen 80;
server_name localhost www.localhost .localhost *.localhost;
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html/public;
client_max_body_size 100M;
location /mailhog/ {
proxy_pass http://mailhog:8025/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Client-Verify SUCCESS;
proxy_read_timeout 1800;
proxy_connect_timeout 1800;
chunked_transfer_encoding on;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
proxy_redirect off;
proxy_buffering off;
}
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass phpfpm:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location /websocket/ {
proxy_pass http://127.0.0.1:6001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400; # Adjust to your needs
}
}
When running the command (that broadcast the event):
docker exec -t shapppes php artisan feed:generate 01h739jr4vk8pq3yefsp22c964
Scoring articles for Sonny Stroman...
Feed created.
Horizon logs the following:
docker exec -t shapppes php artisan horizon
Horizon started successfully.
2023-08-07 13:04:56 App\Actions\Article\Feed\GenerateFeed .......... RUNNING
2023-08-07 13:04:57 App\Actions\Article\Feed\GenerateFeed .... 899.66ms DONE
2023-08-07 13:04:57 App\Providers\FeedGenerated .................... RUNNING
2023-08-07 13:04:57 App\Providers\FeedGenerated ............... 61.82ms DONE
Redis is successfully querying (seen via Laravel Telescope)
eval -- Push the job onto the queue...
redis.call('rpush', KEYS[1], ARGV[1])
-- Push a notification onto the "notify" queue...
redis.call('rpush', KEYS[2], 1) 2 queues:default queues:default:notify {"uuid":"bf2e429e-7702-4758-bedd-d072914a3215","displayName":"App\\Providers\\FeedGenerated","job":"Illuminate\\Queue\\CallQueuedHandler@call","maxTries":null,"maxExceptions":null,"failOnTimeout":false,"backoff":null,"timeout":null,"retryUntil":null,"data":{"commandName":"Illuminate\\Broadcasting\\BroadcastEvent","command":"O:38:\"Illuminate\\Broadcasting\\BroadcastEvent\":14:{s:5:\"event\";O:27:\"App\\Providers\\FeedGenerated\":1:{s:4:\"user\";O:45:\"Illuminate\\Contracts\\Database\\ModelIdentifier\":5:{s:5:\"class\";s:15:\"App\\Models\\User\";s:2:\"id\";s:26:\"01h739jr4vk8pq3yefsp22c964\";s:9:\"relations\";a:4:{i:0;s:4:\"page\";i:1;s:14:\"page.bookmarks\";i:2;s:10:\"page.image\";i:3;s:4:\"tags\";}s:10:\"connection\";s:5:\"mysql\";s:15:\"collectionClass\";N;}}s:5:\"tries\";N;s:7:\"timeout\";N;s:7:\"backoff\";N;s:13:\"maxExceptions\";N;s:10:\"connection\";N;s:5:\"queue\";N;s:15:\"chainConnection\";N;s:10:\"chainQueue\";N;s:19:\"chainCatchCallbacks\";N;s:5:\"delay\";N;s:11:\"afterCommit\";N;s:10:\"middleware\";a:0:{}s:7:\"chained\";a:0:{}}"},"telescope_uuid":"99d54a11-c8fc-489f-8676-a575ab0466bf","id":"bf2e429e-7702-4758-bedd-d072914a3215","attempts":0,"type":"broadcast","tags":["App\\Models\\User:01h739jr4vk8pq3yefsp22c964"],"silenced":false,"pushedAt":"1691413497.6378"}
The event is successfully handled by the listener, but nothing appears to be caught by Soketi (no Docker log, no feedback on the front-end).
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community