Files
meshstream/README.md
Daniel Pupius 8130158c1e feat(cache): priority-based eviction with age protection and Bélády approximation
Replace the flat circular buffer with NodeAwareCache, a smarter eviction
strategy for historical mesh packet data:

- Packets younger than 1 hour are never evicted (recent traffic preserved)
- Under pressure, evict from the lowest-priority type first (neighbor-info
  outlasts node-info; chat messages outlast everything)
- Within a priority tier, evict from the most recently active source node —
  that node will resend soonest, so its old packet is cheapest to lose
  (Bélády approximation; protects flaky/distant node history)
- Node retention window still applies: silent nodes' packets are excluded
  from GetAll and pruned proactively before priority eviction runs

Also:
- Add --cache-retention flag (default 3h) and raise --cache-size default to 5000
- Fix decoder error strings (replace verbose Go errors with short codes)
- Add HTTP security headers middleware to server
- Fix broker dispatchLoop deadlock on source channel close
- Fix make gen-proto scanning web/node_modules for .proto files
- Fix tools target always reinstalling protoc-gen-go (handles stale arch binary)
- Move server port from 8080 to 5446; update Dockerfile, docker-compose, moat.yaml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 20:23:50 +00:00

101 lines
4.1 KiB
Markdown

# Meshstream
Meshstream is a bridge between Meshtastic MQTT networks and web clients, enabling real-time monitoring and visualization of mesh network activity. The server component connects to Meshtastic MQTT servers, decodes mesh packets, and streams this data to web clients using Server Sent Events (SSE). The client-side application then aggregates and visualizes this raw data stream in various interactive views.
Meshstream caches recent network packets on the server side, but does not persist pemanently. Client will receive some historical data upon connection. This provides immediate context and visualization even before new real-time data starts flowing.
![Meshstream Dashboard](./screenshots/dashboard.png)
## Features
- **MQTT to SSE Bridge**: Connects Meshtastic MQTT networks to web clients using Server Sent Events
- **Real-time Map**: Interactive map showing node locations
- **Message Streaming**: Live view of all packets flowing reported on the MQTT topic
- **Telemetry Monitoring**: Track device metrics like battery levels, temperatures, and signal strength
- **Encrypted Channel Support**: Ability to decrypt private channels using pre-shared keys
- **Node Details**: In-depth information about each node in your network
- **Chat Activity**: View channels and text messages
![Network Map](./screenshots/map.png)
## Quick Start
### Using Docker (Recommended)
The easiest way to get started:
```bash
# Clone the repository
git clone https://github.com/your-username/meshstream.git
cd meshstream
# Configure environment variables
cp .env.example .env
# Build and run with Docker Compose
docker-compose up
```
Then visit http://localhost:8080 in your browser.
### Manual Setup
Prerequisites:
- Go 1.24 or later
- Node.js 20 or later
- pnpm (for web UI development)
```bash
# Install dependencies and generate protobuf code
go mod tidy
make gen-proto
# Run the server
make run
# Run the client
make web-run
```
## Configuration
Meshstream can be configured through environment variables, command-line flags, or a `.env` file. All configuration options use the `MESHSTREAM_` prefix.
### Core Configuration
| Environment Variable | Default | Description |
|----------------------|---------|-------------|
| `MESHSTREAM_MQTT_BROKER` | mqtt.bayme.sh | MQTT broker address |
| `MESHSTREAM_MQTT_USERNAME` | meshdev | MQTT username |
| `MESHSTREAM_MQTT_PASSWORD` | large4cats | MQTT password |
| `MESHSTREAM_MQTT_TOPIC_PREFIX` | msh/US/bayarea | MQTT topic prefix for Meshtastic |
| `MESHSTREAM_SERVER_HOST` | localhost | Host to bind the web server |
| `MESHSTREAM_SERVER_PORT` | 8080 | Port for the web server |
| `MESHSTREAM_CACHE_SIZE` | 1000 | Number of packets to cache for new client connections |
| `MESHSTREAM_STATS_INTERVAL` | 30s | Interval for statistics reporting |
| `MESHSTREAM_CHANNEL_KEYS` | LongFast:DefaultKey,... | Comma-separated list of channel:key pairs for decrypting private channels |
> [!NOTE]
> Meshstream can be configured with pre-shared keys to decrypt private encrypted channels. This should only be done when channel participants have explicitly consented to having their messages monitored or when Meshstream is deployed behind an authentication gateway. Remember that decrypting private channels without consent may violate privacy expectations and potentially laws depending on your jurisdiction.
### Web UI Configuration (Build-time)
These must be set at build time (via Docker build args or `web/.env.local`):
| Build Variable | Default | Description |
|----------------|---------|-------------|
| `VITE_SITE_TITLE` | My Mesh | Site title shown in the browser tab |
| `VITE_SITE_DESCRIPTION` | Realtime Meshtastic activity via MQTT. | Meta description |
| `VITE_API_BASE_URL` | _(empty — same origin)_ | API base URL, if serving from a different host |
Maps use [MapLibre GL JS](https://maplibre.org/) with free CartoDB Dark Matter tiles — no API key required.
For complete configuration options, see the Dockerfile and docker-compose.yml.
![Message Stream](./screenshots/stream.png)
![Node Details](./screenshots/node-details.png)
## License
[MIT License](./LICENSE)