Skip to main content
Version: v1 (Current)

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 PatternDescription
dashboard.project.{slug}.attendeesAttendee events
dashboard.project.{slug}.accessAccess control events
dashboard.project.{slug}.socialSocial stream events
dashboard.project.{slug}.formsForm response events
dashboard.project.{slug}.gamesGamification 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.