Article
Building Real-Time Apps with Laravel and WebSockets
When I set out to build Wormhole Systems, a collaborative mapping tool for EVE Online, I knew real-time updates would be essential. Let me explain why WebSockets were the only sensible choice.
The Problem: Mapping a Shifting Universe
EVE Online’s wormhole space is a constantly shifting landscape. Connections between systems appear and collapse unpredictably, and for corporations living in this space, keeping an accurate map is critical for navigation, logistics, and survival.
The challenge? Multiple players are scanning and exploring simultaneously. When someone discovers a new connection or watches one collapse, everyone else needs to see that update instantly. In wormhole space, outdated information can mean flying into a trap or getting stranded.
Why Polling Wasn’t an Option
My first instinct might have been polling: have each client ask the server “anything new?” every few seconds. But consider what that means with 50 connected mappers:
- 50 requests every 2 seconds = 1,500 requests per minute
- Most responses: “No, nothing changed”
- Delays of up to 2 seconds for critical updates
- Wasted bandwidth, wasted server resources
For a mapping tool where split-second awareness matters, this was unacceptable.
WebSockets: Push, Don’t Poll
WebSockets flip the model. Instead of clients constantly asking, the server pushes updates the moment something changes. One player adds a connection, and within milliseconds every other mapper sees it appear on their screen.
The benefits are clear:
- Instant updates: no polling delay
- Efficient: only send data when something actually changes
- Scalable: the server isn’t drowning in redundant requests
Laravel Reverb
Laravel Reverb made implementation straightforward. It’s a first-party WebSocket server that integrates directly with Laravel’s broadcasting system.
// When a connection is added, broadcast to all mappers
class ConnectionDiscovered implements ShouldBroadcastNow
{
public function __construct(
public Connection $connection
) {}
public function broadcastOn(): Channel
{
return new PrivateChannel('map.'.$this->connection->map_id);
}
}
Note the ShouldBroadcastNow interface instead of ShouldBroadcast. The difference matters: ShouldBroadcast pushes the event to your queue, adding latency while it waits to be processed. ShouldBroadcastNow broadcasts immediately, synchronously. For a mapping tool where a new connection needs to appear on everyone’s screen now, that queue delay is unacceptable.
Broadcasting an event is as simple as:
broadcast(new ConnectionDiscovered($connection));
Frontend with Vue and Laravel Echo
On the frontend, Laravel Echo handles the WebSocket connection. The classic approach uses method chaining to subscribe to channels:
Echo.private(`map.${mapId}`)
.listen('ConnectionDiscovered', (e) => {
addConnectionToMap(e.connection);
})
.listen('ConnectionCollapsed', (e) => {
removeConnectionFromMap(e.connection);
});
Echo Hooks for Vue
Laravel Echo now ships with Vue composables that make subscriptions cleaner. The useEcho hook handles everything in a single call (channel, event, and callback) with automatic cleanup when your component unmounts:
<script setup>
import { useEcho } from '@laravel/echo-vue';
import { ref } from 'vue';
const connections = ref([]);
const mapId = 'map-123';
useEcho(`map.${mapId}`, 'ConnectionDiscovered', (e) => {
connections.value.push(e.connection);
});
useEcho(`map.${mapId}`, 'ConnectionCollapsed', (e) => {
connections.value = connections.value.filter(c => c.id !== e.connection.id);
});
</script>
No more forgetting to call Echo.leave(). The hook integrates with Vue’s lifecycle, so when the component unmounts, the subscription is cleaned up automatically. This is especially useful in SPAs where map views mount and unmount as players navigate.
When an event comes in, Vue’s reactivity takes care of updating the UI. The map stays in sync across all connected clients without any manual refresh.
The Result
Wormhole Systems now handles real-time collaborative mapping for EVE Online corporations. Multiple players can map simultaneously, seeing each other’s discoveries and updates as they happen. The WebSocket architecture keeps everything responsive while using a fraction of the resources that polling would have required.
If you’re building anything collaborative, whether it’s a mapping tool, a chat system, or a live dashboard, WebSockets with Laravel Reverb are worth considering. The initial setup is minimal, and the payoff in user experience and server efficiency is substantial.
Tim Kunze
Web Developer, Austria