Notification Server Demo¶
The notification_server_demo module provides demo interfaces for testing and learning how to use the Notification Server module.
Optional Module
This is an optional sub-module that provides demo functionality. It's not required for production use of the Notification Server module.
Overview¶
The demo module includes:
- HTTP Notification Demo - Test publishing notifications via HTTP API
- WebSocket Demo - Test real-time WebSocket communication
- Interactive interfaces - User-friendly forms for testing features
- Real-time feedback - See notifications in action
Installation¶
# Enable the demo module
drush en notification_server_demo
# Or via Drupal UI
# Go to: /admin/modules
# Find "Notification Server Demo" and enable it
Permissions¶
The demo module provides these permissions:
access notification_server http demo- Access to HTTP notification demoaccess notification_server websocket demo- Access to WebSocket demo interface
Demo Module Permission
Note that the WebSocket demo permission in the actual code does not have restrict access: true set, unlike the HTTP demo permission. This means it may be available to more users by default.
Grant these permissions to appropriate roles:
- Go to
/admin/people/permissions - Find the notification server demo permissions
- Grant to roles that need testing access (e.g., administrators, developers)
Demo Interfaces¶
HTTP Notification Demo¶
URL: /admin/config/system/notification-server/http-demo
Features¶
- Channel Selection - Choose which channel to send notifications to
- Message Input - Enter custom notification messages
- Message Type Selection - Test different message formats
- Response Display - View server responses and status
- Error Handling - See how errors are handled
Usage¶
-
Navigate to the demo: Visit
/admin/config/system/notification-server/http-demo -
Enter channel name: Type the name of the channel you want to send to
-
Enter message: Choose message format:
- Simple text:
Hello, World! -
JSON object:
{"type": "info", "message": "Test notification"} -
Send notification: Click "Send Notification" button
-
View results: Check the response area for:
- Success confirmations
- Error messages
- Server response data
Example Messages¶
Simple Message:
Structured Message:
Channel: user_updates
Message: {
"type": "profile_update",
"user_id": 123,
"changes": ["email", "name"],
"timestamp": 1672531200
}
Rich Notification:
Channel: content_updates
Message: {
"event": "article_published",
"title": "Breaking News",
"author": "John Doe",
"category": "Technology",
"urgency": "high"
}
WebSocket Demo¶
URL: /admin/config/system/notification-server/websocket-demo
Features¶
- Client Connection Management - Connect/disconnect WebSocket clients
- Channel Subscription - Subscribe/unsubscribe from channels
- Real-time Message Display - View incoming notifications live
- Connection Status - Monitor WebSocket connection state
- Message Log - History of all received messages
- Interactive Controls - Easy-to-use interface for testing
Interface Components¶
- Client Management Section
- Client ID input field
- Connect/Disconnect buttons
-
Connection status indicator
-
Subscription Management Section
- Channel name input
- Subscribe/Unsubscribe buttons
-
List of subscribed channels
-
Notification Information
- Instructions for sending notifications
-
Code examples for programmatic usage
-
Real-time Log
- Timestamped message display
- Color-coded message types
- Automatic scrolling
- Message count limiting
Usage Steps¶
- Connect Client:
- Enter a client ID (or leave blank for auto-generation)
- Click "Connect" button
-
Wait for connection confirmation
-
Subscribe to Channels:
- Enter channel name (e.g.,
test,alerts,updates) - Click "Subscribe" button
-
Verify channel appears in subscribed list
-
Send Test Notifications:
- Use the HTTP demo to send messages to subscribed channels
- Or use Drush/code to publish notifications
-
Watch messages appear in real-time log
-
Test Multiple Channels:
- Subscribe to multiple channels
- Send messages to different channels
- Observe selective message delivery
Example Usage Flow¶
# Step 1: Connect WebSocket client
# - Enter client ID: demo_client_123
# - Click Connect
# - Status should show: "Connected to WebSocket server"
# Step 2: Subscribe to test channel
# - Enter channel: test_notifications
# - Click Subscribe
# - Channel should appear in subscribed list
# Step 3: Send test message (using HTTP demo or Drush)
drush php-eval "
\$client = \Drupal::service('notification_server.client');
\$client->publishNotification('test_notifications', 'Hello from Drush!');
"
# Step 4: Observe message in WebSocket demo
# - Message should appear in real-time log
# - Timestamp and content should be displayed
Code Examples¶
Using Demo for Development¶
The demo module serves as excellent reference code for implementing notifications in your own modules.
Form Integration Example¶
From the HTTP demo form:
<?php
// Form submit handler from NotificationHttpDemoForm
public function submitForm(array &$form, FormStateInterface $form_state) {
$channel = $form_state->getValue('channel');
$message = $form_state->getValue('message');
// Parse JSON if possible
$decoded_message = json_decode($message, TRUE);
$final_message = $decoded_message !== NULL ? $decoded_message : $message;
// Send notification
$notification_client = \Drupal::service('notification_server.client');
$result = $notification_client->publishNotification($channel, $final_message);
if ($result !== NULL) {
$this->messenger()->addStatus($this->t('Notification sent successfully to channel "@channel".', [
'@channel' => $channel,
]));
} else {
$this->messenger()->addError($this->t('Failed to send notification to channel "@channel".', [
'@channel' => $channel,
]));
}
}
JavaScript WebSocket Integration¶
From the WebSocket demo JavaScript:
// Initialize WebSocket connection
initializeWebSocket: function (websocketUrl) {
if (!websocketUrl) {
this.updateConnectionStatus('error', 'WebSocket URL not configured');
return;
}
try {
const wsUrl = `${websocketUrl}?clientId=${encodeURIComponent(this.clientId)}`;
this.websocket = new WebSocket(wsUrl);
this.setupWebSocketHandlers();
} catch (error) {
this.updateConnectionStatus('error', 'Failed to initialize WebSocket connection');
}
},
// Handle incoming messages
handleIncomingMessage: function (data) {
if (data.type === 'notification') {
this.showMessage(`Received message on channel "${data.channel}": ${data.data.message}`, 'success');
}
},
// Subscribe to channel
sendSubscription: function (channel) {
if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
this.websocket.send(JSON.stringify({
type: 'subscribe',
clientId: this.clientId,
channel: channel
}));
}
}
Testing Scenarios¶
Basic Functionality Test¶
- Setup: Enable demo module, configure notification server
- Test HTTP: Send simple message via HTTP demo
- Test WebSocket: Connect client and subscribe to channel
- Verify: Send HTTP message, confirm WebSocket receives it
Multi-Channel Test¶
- Subscribe: Connect to multiple channels in WebSocket demo
- Send: Use HTTP demo to send messages to different channels
- Verify: Each channel receives only its messages
Error Handling Test¶
- Invalid Channel: Try sending to non-existent channel
- Invalid Client: Use invalid client ID in WebSocket
- Network Issues: Disconnect notification server and test error handling
Performance Test¶
- Multiple Clients: Open multiple WebSocket demo tabs
- Rapid Messages: Send many messages quickly via HTTP demo
- Monitor: Check for message delivery and connection stability
Educational Value¶
Learning WebSocket Concepts¶
The demo helps understand:
- Connection Management: How WebSocket connections are established
- Message Formats: JSON message structure for subscriptions and notifications
- Error Handling: How connection errors are handled
- State Management: Tracking connection and subscription states
Understanding Channel Architecture¶
Demonstrates:
- Channel Creation: How channels are created and configured
- Access Control: How client access to channels is managed
- Message Routing: How messages are delivered to subscribed clients
- Subscription Management: Dynamic channel subscription/unsubscription
Real-time Communication Patterns¶
Shows practical examples of:
- Pub/Sub Pattern: Publisher/subscriber messaging model
- Event-Driven Architecture: Real-time event handling
- Bidirectional Communication: Two-way client-server interaction
- Connection Resilience: Handling connection drops and reconnections
Demo Module Structure¶
Files and Components¶
modules/notification_server_demo/
├── notification_server_demo.info.yml # Module definition
├── notification_server_demo.permissions.yml # Permission definitions
├── notification_server_demo.routing.yml # Route definitions
├── notification_server_demo.libraries.yml # Asset libraries
├── notification_server_demo.module # Hook implementations
├── css/
│ └── notification-demo.css # Demo styling
├── js/
│ └── notification-websocket-demo.js # WebSocket demo JavaScript
├── src/
│ ├── Controller/
│ │ └── NotificationWebSocketDemoController.php # WebSocket demo controller
│ └── Form/
│ └── NotificationHttpDemoForm.php # HTTP demo form
└── templates/
├── notification-log-entry.html.twig # Log entry template
└── notification-websocket-demo.html.twig # WebSocket demo template
Key Components¶
HTTP Demo Form (NotificationHttpDemoForm.php):
- Provides form interface for sending notifications
- Handles message validation and JSON parsing
- Demonstrates proper service usage
WebSocket Demo Controller (NotificationWebSocketDemoController.php):
- Renders WebSocket demo interface
- Passes configuration to JavaScript
- Demonstrates client ID management
WebSocket JavaScript (notification-websocket-demo.js):
- Complete WebSocket client implementation
- Connection management and error handling
- Real-time message display and logging
Customization¶
Extending the Demo¶
You can extend the demo for your specific needs:
Add Custom Message Types¶
<?php
// In your custom form
$form['message_type'] = [
'#type' => 'select',
'#title' => $this->t('Message Type'),
'#options' => [
'simple' => $this->t('Simple Text'),
'user_alert' => $this->t('User Alert'),
'system_event' => $this->t('System Event'),
'custom' => $this->t('Custom JSON'),
],
];
Add Channel Presets¶
<?php
// Predefined channels for easy testing
$form['channel_preset'] = [
'#type' => 'select',
'#title' => $this->t('Quick Channel Selection'),
'#options' => [
'alerts' => $this->t('System Alerts'),
'user_updates' => $this->t('User Updates'),
'content_changes' => $this->t('Content Changes'),
'custom' => $this->t('Custom Channel'),
],
];
Add Message Templates¶
// JavaScript templates for common messages
const messageTemplates = {
userLogin: {
type: 'user_event',
action: 'login',
user_id: 123,
timestamp: Date.now()
},
contentUpdate: {
type: 'content_event',
action: 'update',
content_id: 456,
title: 'Sample Article'
}
};
Production Considerations¶
Security¶
- Remove demo module in production environments
- Demo exposes functionality that shouldn't be available to end users
- Use for development/testing only
Performance¶
- Demo interfaces are not optimized for high-traffic use
- Logging overhead may impact performance
- Disable demo before performance testing
Access Control¶
- Restrict demo permissions to developers and administrators
- Monitor demo usage in staging environments
- Document demo procedures for team members
Troubleshooting Demo Issues¶
HTTP Demo Not Working¶
- Check permissions: Ensure user has demo access permission
- Verify configuration: Confirm notification server URLs are set
- Test connectivity: Use curl to test HTTP API directly
- Check logs: Review Drupal and notification server logs
WebSocket Demo Connection Fails¶
- Check WebSocket URL: Ensure correct
ws://orwss://format - Verify client ID: Confirm client ID generation works
- Test network: Check firewall and proxy settings
- Browser console: Look for JavaScript errors
Messages Not Appearing¶
- Confirm subscription: Verify channel subscription succeeded
- Check channel names: Ensure exact channel name match
- Verify access: Confirm client has channel access
- Test with simple data: Use basic string messages first
Demo Interface Issues¶
- Clear cache: Run
drush crto clear Drupal caches - Check JavaScript: Verify no console errors
- Disable browser extensions: Test without ad blockers
- Try different browser: Rule out browser-specific issues
Next Steps¶
After using the demo module:
- Review demo code to understand implementation patterns
- Build custom integration using learned concepts
- Implement proper error handling in your production code
- Add logging and monitoring for production notifications
- Disable demo module in production environments