georgeboot/laravel-echo-api-gateway
Connect Laravel Echo to AWS API Gateway WebSocket APIs. This package enables realtime broadcasting and channel subscriptions through API Gateway, so you can use serverless WebSockets without running a dedicated Echo server.
Start by installing the package and publishing its config:
composer require <vendor>/<package>
php artisan vendor:publish --provider="<Vendor>\\<Package>\\ServiceProvider"
Then configure the basics in .env/config:
On the frontend, install a compatible laravel-echo version. As of 0.5.9, both Laravel Echo v1 (^1.10) and v2 are supported. Configure Echo to point at your API Gateway WebSocket endpoint and Laravel auth endpoint, then create a simple private-channel listener to verify end-to-end delivery:
window.Echo = new Echo({
broadcaster: 'pusher',
wsHost: import.meta.env.VITE_WS_HOST,
wsPort: 443,
wssPort: 443,
forceTLS: true,
enabledTransports: ['ws', 'wss'],
authEndpoint: '/broadcasting/auth',
auth: {
headers: { Authorization: `Bearer ${token}` },
},
});
Echo.private(`orders.${orderId}`)
.listen('.OrderUpdated', (event) => {
console.log(event);
});
First use case to validate: broadcast a ShouldBroadcast event to a private channel and confirm the browser receives it, then disconnect/reconnect the socket and confirm the listener still receives events. That exercises the main fixes in 0.5.9.
Backend events and channels
Use standard Laravel broadcasting patterns for events:
class OrderUpdated implements ShouldBroadcast
{
public function broadcastOn(): array
{
return [new PrivateChannel("orders.{$this->order->id}")];
}
public function broadcastAs(): string
{
return 'OrderUpdated';
}
}
Authorize channels server-side in routes/channels.php or through the package’s channel-auth callback. Keep channel names consistent between backend and frontend, and prefer private/presence channels for anything user-specific.
Frontend listeners
Use Echo’s normal subscription APIs, but attach subscription error handlers explicitly:
Echo.private(`orders.${orderId}`)
.listen('.OrderUpdated', handleOrderUpdated)
.error((error) => {
console.error('Subscription failed', error);
});
For presence channels, also handle here, joining, and leaving. For notifications, use Echo’s notification helpers if your event payloads follow Laravel’s notification broadcast format.
Connection lifecycle
Treat API Gateway WebSocket connections as ephemeral. If your application needs server-side fanout, store connection IDs on $connect, remove them on $disconnect, and prune stale IDs when API Gateway returns GoneException/410. Route $default messages deliberately and keep $connect authentication strict.
Because API Gateway enforces a maximum connection duration, build your UI around reconnects rather than assuming a permanently open socket. Listen for connection state changes and subscription success/error events. On reconnect, confirm private/presence channels are re-authorized and listeners are still attached.
Deployment workflow
php artisan config:clearPostToConnection^1.10; older v1 versions are not covered. Laravel Echo v2 is also supported. Pin and rebuild frontend dependencies intentionally..error() handlers, enable Echo debug logging in non-production, and inspect WebSocket frames in browser devtools. Check /broadcasting/auth responses and CORS/auth headers when private channels fail.ws/wss port is a common cause of “connection established but no events.” Verify the exact WebSocket URL in the browser network tab.GoneException/410 responses and remove dead connection IDs. Do not retry indefinitely against disconnected clients.$connect, $disconnect, and $default routing; Laravel logs help diagnose broadcast and channel-auth failures. Correlate by connection ID and request ID.$connect route. These are the places most likely to conflict with security hardening or reconnect changes.How can I help you explore Laravel packages today?