Real-time Events Guide
This guide covers how to subscribe to and handle real-time events in GxP using WebSockets via Pusher.
Overview
GxP broadcasts real-time events for key actions, allowing you to:
- Receive instant updates when data changes
- Build live dashboards and monitoring tools
- Trigger immediate actions in your application
- Keep multiple clients synchronized
WebSocket Connection
GxP uses Pusher for WebSocket communication. To connect:
Configuration
// Using Laravel Echo
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
const echo = new Echo({
broadcaster: 'pusher',
key: 'your-pusher-key',
cluster: 'us2',
forceTLS: true,
authEndpoint: 'https://api.gramercy.cloud/broadcasting/auth',
auth: {
headers: {
Authorization: 'Bearer YOUR_TOKEN'
}
}
});
Direct Pusher Connection
const pusher = new Pusher('your-pusher-key', {
cluster: 'us2',
forceTLS: true,
authEndpoint: 'https://api.gramercy.cloud/broadcasting/auth',
auth: {
headers: {
Authorization: 'Bearer YOUR_TOKEN'
}
}
});
Channel Types
GxP uses private channels that require authentication:
| Channel Pattern | Description |
|---|---|
dashboard.project.{slug}.attendees | Attendee events |
dashboard.project.{slug}.access | Access control events |
dashboard.project.{slug}.social | Social stream events |
dashboard.project.{slug}.forms | Form response events |
dashboard.project.{slug}.games | Gamification events |
Subscribing to Events
Using Laravel Echo
// Subscribe to attendee events
echo.private(`dashboard.project.${projectSlug}.attendees`)
.listen('AttendeeCreated', (e) => {
console.log('New attendee:', e);
})
.listen('AttendeeUpdated', (e) => {
console.log('Updated attendee:', e);
})
.listen('AttendeeDeleted', (e) => {
console.log('Deleted attendee:', e);
});
Using Pusher Directly
const channel = pusher.subscribe(`private-dashboard.project.${projectSlug}.attendees`);
channel.bind('AttendeeCreated', (data) => {
console.log('New attendee:', data);
});
channel.bind('AttendeeUpdated', (data) => {
console.log('Updated attendee:', data);
});
Event Reference
Attendee Events
AttendeeCreated
Fired when a new attendee is created.
Channel: dashboard.project.{projectSlug}.attendees
Payload:
{
"attendee_id": 12345,
"project_id": 1,
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"attendee_type_id": 1,
"created_at": "2024-01-15T10:30:00Z"
}
AttendeeUpdated
Fired when an attendee is modified.
Payload:
{
"attendee_id": 12345,
"project_id": 1,
"changes": {
"email": "jane.updated@example.com"
},
"updated_at": "2024-01-15T11:00:00Z"
}
AttendeeDeleted
Fired when an attendee is removed.
Payload:
{
"attendee_id": 12345,
"project_id": 1,
"deleted_at": "2024-01-15T12:00:00Z"
}
Access Control Events
AccessGranted
Fired when access is granted at an access point.
Channel: dashboard.project.{projectSlug}.access
Payload:
{
"attendee_id": 12345,
"access_point_id": 1,
"access_zone_id": 2,
"credential_id": 100,
"direction": "in",
"timestamp": "2024-01-15T14:30:00Z"
}
AccessDenied
Fired when access is denied.
Payload:
{
"credential_value": "ABC123",
"access_point_id": 1,
"reason": "not_authorized",
"timestamp": "2024-01-15T14:31:00Z"
}
Social Stream Events
PostCreated
Fired when a new social post is created.
Channel: dashboard.project.{projectSlug}.social
Payload:
{
"post_id": 500,
"stream_id": 10,
"content": "Having a great time at the conference!",
"author": {
"id": 12345,
"name": "Jane Smith"
},
"created_at": "2024-01-15T15:00:00Z"
}
Gamification Events
PointsAwarded
Fired when points are awarded to an attendee.
Channel: dashboard.project.{projectSlug}.games
Payload:
{
"game_id": 1,
"attendee_id": 12345,
"points": 50,
"reason": "session_attendance",
"total_points": 250,
"awarded_at": "2024-01-15T16:00:00Z"
}
Error Handling
Connection Errors
echo.connector.pusher.connection.bind('error', (err) => {
console.error('WebSocket error:', err);
});
Subscription Errors
channel.bind('pusher:subscription_error', (status) => {
console.error('Subscription error:', status);
});
Best Practices
1. Reconnection Handling
echo.connector.pusher.connection.bind('state_change', (states) => {
if (states.current === 'disconnected') {
// Handle disconnection
}
if (states.current === 'connected') {
// Handle reconnection
}
});
2. Unsubscribe When Done
// Unsubscribe from a channel
echo.leave(`dashboard.project.${projectSlug}.attendees`);
// Disconnect entirely
echo.disconnect();
3. Debounce Rapid Events
import { debounce } from 'lodash';
const handleUpdate = debounce((data) => {
// Handle the event
}, 100);
channel.bind('AttendeeUpdated', handleUpdate);
4. Handle Offline State
window.addEventListener('offline', () => {
// Queue events or show offline indicator
});
window.addEventListener('online', () => {
// Reconnect and sync state
});
Cross-Reference with REST API
Events triggered by REST API operations include cross-references:
{
"x-triggered-by": {
"operation_id": "v1.project.attendees.store",
"request_id": "abc123"
}
}
This allows you to correlate WebSocket events with API requests.
Rate Limiting
WebSocket connections are subject to rate limits:
- Connections: Max 100 per user
- Subscriptions: Max 100 channels per connection
- Message rate: No limit on receiving, but broadcasting from client is not supported
Debugging
Enable Pusher logging for debugging:
Pusher.logToConsole = true;
Or use the Pusher Debug Console in your dashboard.