feat: externalize cluster integration and API

This commit is contained in:
2025-10-19 21:52:55 +02:00
parent 8de77e225d
commit a7018f53f3
4 changed files with 1245 additions and 1270 deletions

204
README.md
View File

@@ -1,182 +1,114 @@
# SPORE UI
# SPORE UI Frontend
Zero-configuration web interface for monitoring and managing SPORE embedded systems.
Frontend web interface for monitoring and managing SPORE embedded systems. Now works in conjunction with the SPORE Gateway backend service.
## Architecture
This frontend server works together with the **SPORE Gateway** (spore-gateway) backend service:
- **spore-ui**: Serves the static frontend files and provides the user interface
- **spore-gateway**: Handles UDP node discovery, API endpoints, and WebSocket connections
## Features
- **🌐 Cluster Monitoring**: Real-time view of all cluster members with auto-discovery
- **🌐 Cluster Monitoring**: Real-time view of all cluster members via spore-gateway
- **📊 Node Details**: Detailed system information including running tasks and available endpoints
- **🚀 OTA**: Clusterwide over-the-air firmware updates
- **📱 Responsive**: Works on all devices and screen sizes
- **🖥️ Terminal**: Terminal for interacting with a node's WebSocket
- **🔗 Gateway Integration**: Seamlessly connects to spore-gateway for all backend functionality
## Screenshots
### Cluster
![UI](./assets/cluster.png)
![UI](./assets/cluster.png)
### Topology
![UI](./assets/topology.png)
![UI](./assets/topology.png)
### Monitoring
![UI](./assets/monitoring.png)
![UI](./assets/monitoring.png)
### Firmware
![UI](./assets/firmware.png)
## Getting Started
### Prerequisites
1. **Install dependencies**: `npm install`
2. **Start the server**: `npm start`
3. **Open in browser**: `http://localhost:3001`
2. **Start spore-gateway**: `./spore-gateway` (in the spore-gateway directory)
3. **Start frontend server**: `npm start`
## API Endpoints
### Access
- **Frontend UI**: `http://localhost:3000`
- **API Backend**: spore-gateway runs on port 3001
- **WebSocket**: Connects to spore-gateway on port 3001
- **`/`** - Main UI page
- **`/api/cluster/members`** - Get cluster member information
- **`/api/tasks/status`** - Get task status
- **`/api/node/status`** - Get system status
- **`/api/node/status/:ip`** - Get status from specific node
## API Integration
The frontend automatically connects to the spore-gateway for:
- **Cluster Discovery**: `/api/discovery/*` endpoints
- **Node Management**: `/api/node/*` endpoints
- **Task Monitoring**: `/api/tasks/*` endpoints
- **Real-time Updates**: WebSocket connections via `/ws`
## Technologies Used
- **Backend**: Express.js, Node.js
- **Backend Integration**: Express.js server connecting to spore-gateway
- **Frontend**: Vanilla JavaScript, CSS3, HTML5
- **Framework**: Custom component-based architecture
- **API**: SPORE Embedded System API
- **API**: SPORE Embedded System API via spore-gateway
- **Design**: Glassmorphism, CSS Grid, Flexbox
## UDP Heartbeat Discovery
## Development
The backend now includes automatic UDP heartbeat-based discovery for SPORE nodes on the network. This eliminates the need for hardcoded IP addresses and provides a self-healing, scalable solution for managing SPORE clusters.
### 🚀 How It Works
1. **UDP Server**: The backend listens on port 4210 for UDP messages
2. **Heartbeat Message**: Nodes send `CLUSTER_HEARTBEAT` messages to broadcast address `255.255.255.255:4210`
3. **Auto Configuration**: When a heartbeat message is received, the source IP is automatically used to configure the SporeApiClient
4. **Dynamic Updates**: The system automatically switches to the most recently seen node as the primary connection
5. **Health Monitoring**: Continuous monitoring of node availability with automatic failover
### 📡 Heartbeat Protocol
- **Port**: 4210 (configurable via `UDP_PORT` constant)
- **Message**: `CLUSTER_HEARTBEAT` (configurable via `HEARTBEAT_MESSAGE` constant)
- **Broadcast**: `255.255.255.255:4210`
- **Protocol**: UDP broadcast listening
- **Auto-binding**: Automatically binds to the specified port on startup
### 🔧 Setup Instructions
#### Backend Setup
```bash
# Start the backend server
npm start
# The server will automatically:
# - Start HTTP server on port 3001
# - Start UDP heartbeat server on port 4210
# - Wait for CLUSTER_HEARTBEAT messages
### File Structure
```
spore-ui/
├── public/ # Static frontend files
│ ├── index.html # Main HTML page
│ ├── scripts/ # JavaScript components
│ └── styles/ # CSS stylesheets
├── index.js # Simple static file server
└── package.json # Node.js dependencies
```
#### Node Configuration
SPORE nodes should send heartbeat messages periodically:
### Key Changes
- **Simplified Backend**: Now only serves static files
- **Gateway Integration**: All API calls go through spore-gateway
- **WebSocket Proxy**: Real-time updates via spore-gateway
- **UDP Discovery**: Handled by spore-gateway service
## Troubleshooting
### Common Issues
**Frontend not connecting to gateway**
```bash
# Recommended: Send every 30-60 seconds
# Message format: "CLUSTER_HEARTBEAT:hostname"
# Target: 255.255.255.255:4210
```
### 🌐 Cluster Endpoints
#### Cluster Management
- `GET /api/discovery/nodes` - View all cluster nodes and current status
- `POST /api/discovery/refresh` - Manually trigger cluster refresh
- `POST /api/discovery/primary/:ip` - Manually set a specific node as primary
- `POST /api/discovery/random-primary` - Randomly select a new primary node
#### Health Monitoring
- `GET /api/health` - Comprehensive health check including cluster status
### 🧪 Testing & Development
#### Test Scripts
```bash
# Send discovery messages to test the system
npm run test-discovery broadcast
# Send to specific IP
npm run test-discovery 192.168.1.100
# Send multiple messages
npm run test-discovery broadcast 5
# Test random primary node selection
npm run test-random-selection
# Monitor discovery in real-time
npm run demo-discovery
```
#### Manual Testing
```bash
# Check discovery status
curl http://localhost:3001/api/discovery/nodes
# Check health
# Check if spore-gateway is running
curl http://localhost:3001/api/health
# Manual refresh
curl -X POST http://localhost:3001/api/discovery/refresh
# Random primary selection
curl -X POST http://localhost:3001/api/discovery/random-primary
# Set specific primary
curl -X POST http://localhost:3001/api/discovery/primary/192.168.1.100
# Verify gateway health
# Should return gateway health status
```
### 🔍 Troubleshooting
#### Common Issues
**No Nodes Discovered**
**WebSocket connection issues**
```bash
# Check if backend is running
curl http://localhost:3001/api/health
# Check WebSocket endpoint
curl http://localhost:3001/api/test/websocket
# Verify UDP port is open
netstat -tulpn | grep 4210
# Send test discovery message
npm run test-discovery broadcast
# Verify gateway WebSocket server is running
```
**UDP Port Already in Use**
**No cluster data**
```bash
# Check for conflicting processes
netstat -tulpn | grep 4210
# Kill conflicting processes or change port in code
# Restart backend server
```
**Client Not Initialized**
```bash
# Check discovery status
# Check gateway discovery status
curl http://localhost:3001/api/discovery/nodes
# Verify nodes are sending discovery messages
# Check network connectivity
# Verify SPORE nodes are sending heartbeat messages
```
#### Debug Commands
```bash
# Check discovery status
curl http://localhost:3001/api/discovery/nodes
## Architecture Benefits
# Check health
curl http://localhost:3001/api/health
# Manual refresh
curl -X POST http://localhost:3001/api/discovery/refresh
# Set primary node
curl -X POST http://localhost:3001/api/discovery/primary/192.168.1.100
```
1. **Separation of Concerns**: Frontend handles UI, gateway handles backend logic
2. **Scalability**: Gateway can handle multiple frontend instances
3. **Maintainability**: Clear separation between presentation and business logic
4. **Performance**: Gateway can optimize API calls and caching
5. **Reliability**: Gateway provides failover and health monitoring