php
52 lines · 9 steps
Server-Sent Events in Laravel
A controller streams live notifications to the browser over a long-lived HTTP connection using Server-Sent Events.
Explained by
highlit
1<?php
2
3namespace App\Http\Controllers;
4
5use Illuminate\Http\Request;
6use Symfony\Component\HttpFoundation\StreamedResponse;
7
8class EventStreamController extends Controller
9{
10 public function stream(Request $request): StreamedResponse
11 {
12 $response = new StreamedResponse(function () use ($request) {
13 $lastId = (int) $request->header('Last-Event-ID', 0);
14
15 while (! connection_aborted()) {
16 $events = Notification::query()
17 ->where('id', '>', $lastId)
18 ->orderBy('id')
19 ->limit(20)
20 ->get();
21
22 foreach ($events as $event) {
23 $lastId = $event->id;
24
25 echo 'id: ' . $event->id . "\n";
26 echo 'event: ' . $event->type . "\n";
27 echo 'data: ' . json_encode([
28 'title' => $event->title,
29 'body' => $event->body,
30 'at' => $event->created_at->toIso8601String(),
31 ]) . "\n\n";
32 }
33
34 echo ": heartbeat\n\n";
35
36 if (ob_get_level() > 0) {
37 ob_flush();
38 }
39 flush();
40
41 sleep(3);
42 }
43 });
44
45 $response->headers->set('Content-Type', 'text/event-stream');
46 $response->headers->set('Cache-Control', 'no-cache');
47 $response->headers->set('Connection', 'keep-alive');
48 $response->headers->set('X-Accel-Buffering', 'no');
49
50 return $response;
51 }
52}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Server-Sent Events keep one HTTP connection open and push newline-delimited text frames instead of polling repeatedly.
- 2Tracking a last-seen id lets the stream resume exactly where the client left off after a reconnect.
- 3Explicit output flushing and buffering-disabled headers are essential to actually deliver events as they happen.
Related explainers
java
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
Real-time chat over STOMP WebSockets in Spring
websockets
stomp
messaging
Intermediate
8 steps
php
<?php namespace App\Actions\Imports;
Streaming CSV imports with Laravel batches
lazy-collections
job-batching
streaming
Advanced
9 steps
php
namespace App\Providers; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Log;
Catching N+1 queries with Eloquent strict mode in Laravel
n+1 queries
strict mode
eager loading
Intermediate
7 steps
php
<?php namespace App\Support;
Recursively finding files with SPL iterators in PHP
recursion
iterators
filesystem
Intermediate
7 steps
php
<?php namespace App\Http\Requests;
A validated date-range value object in PHP
value-object
validation
immutability
Intermediate
7 steps
php
<?php namespace App\Http\Controllers\Api;
Building a cursor-paginated feed in Laravel
cursor-pagination
eager-loading
validation
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/server-sent-events-in-laravel-explained-php-3550/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.