fix websocket

This commit is contained in:
lelo 2025-03-22 17:06:24 +00:00
parent f22b2df7bb
commit f2e5e2f314
4 changed files with 66 additions and 64 deletions

74
app.py
View File

@ -10,7 +10,7 @@ import diskcache
import threading import threading
import json import json
import time import time
from flask_socketio import SocketIO from flask_socketio import SocketIO, emit
import geoip2.database import geoip2.database
from functools import lru_cache from functools import lru_cache
from urllib.parse import urlparse, unquote from urllib.parse import urlparse, unquote
@ -34,7 +34,8 @@ if os.environ.get('FLASK_ENV') == 'production':
app.add_url_rule('/dashboard', view_func=a.dashboard) app.add_url_rule('/dashboard', view_func=a.dashboard)
app.add_url_rule('/network', view_func=a.network) app.add_url_rule('/network', view_func=a.network)
socketio = SocketIO(app) socketio = SocketIO(app, async_mode='eventlet')
background_thread_running = False
# Global variables to track the number of connected clients and the background thread # Global variables to track the number of connected clients and the background thread
clients_connected = 0 clients_connected = 0
@ -312,41 +313,40 @@ def crawl_and_cache(subpath):
return json.dumps({"cached_files": cached_files}, indent=4), 200 return json.dumps({"cached_files": cached_files}, indent=4), 200
def query_recent_connections(): def query_recent_connections():
global clients_connected global clients_connected, background_thread_running
last_connections = None # Initialize with None to ensure the first emit happens background_thread_running = True
while clients_connected > 0: last_connections = None
rows = a.return_file_access() try:
while clients_connected > 0:
rows = a.return_file_access()
connections = [
{
'timestamp': row[0],
'full_path': row[1],
'ip_address': row[2],
'user_agent': row[3],
'referrer': row[4]
}
for row in rows
]
# Convert rows to dictionaries for the client. if connections != last_connections:
connections = [ socketio.emit('recent_connections', connections)
{ last_connections = connections.copy()
'timestamp': row[0],
'full_path': row[1],
'ip_address': row[2],
'user_agent': row[3],
'referrer': row[4]
}
for row in rows
]
# Only emit if there's a change compared to the previous connections. socketio.sleep(1)
if connections != last_connections: finally:
socketio.emit('recent_connections', connections) background_thread_running = False
last_connections = connections.copy() # Store a copy of the current state print("No clients connected; stopping query thread.")
time.sleep(1)
print("No clients connected; stopping query thread.")
@socketio.on('connect') @socketio.on('connect')
def handle_connect(): def handle_connect(auth=None):
global clients_connected, background_thread global clients_connected, background_thread_running
clients_connected += 1 clients_connected += 1
print("Client connected. Total clients:", clients_connected) print("Client connected. Total clients:", clients_connected)
with thread_lock: with thread_lock:
# Start the background task if it's not already running. if not background_thread_running:
if background_thread is None or not background_thread.is_alive(): socketio.start_background_task(query_recent_connections)
background_thread = socketio.start_background_task(query_recent_connections)
print("Started background query task.") print("Started background query task.")
@socketio.on('disconnect') @socketio.on('disconnect')
@ -355,6 +355,20 @@ def handle_disconnect():
clients_connected -= 1 clients_connected -= 1
print("Client disconnected. Total clients:", clients_connected) print("Client disconnected. Total clients:", clients_connected)
@socketio.on('request_initial_data')
def handle_request_initial_data():
rows = a.return_file_access()
connections = [
{
'timestamp': row[0],
'full_path': row[1],
'ip_address': row[2],
'user_agent': row[3],
'referrer': row[4]
}
for row in rows
]
emit('recent_connections', connections)
# Catch-all route to serve the single-page application template. # Catch-all route to serve the single-page application template.
@app.route('/', defaults={'path': ''}) @app.route('/', defaults={'path': ''})

View File

@ -16,40 +16,32 @@ services:
propagation: rshared propagation: rshared
environment: environment:
- FLASK_APP=app.py - FLASK_APP=app.py
- FLASK_RUN_HOST=0.0.0.0
- FLASK_ENV=production - FLASK_ENV=production
networks: networks:
- traefik - traefik
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
# ---------------------------------------------------- # HTTP router (port 80), redirecting to HTTPS
# HTTP router: Listen on entrypoint "web" (port 80)
# and apply a middleware to force redirect to HTTPS
# ----------------------------------------------------
- "traefik.http.routers.bethaus-app.rule=Host(`app.bethaus-speyer.de`)" - "traefik.http.routers.bethaus-app.rule=Host(`app.bethaus-speyer.de`)"
- "traefik.http.routers.bethaus-app.entrypoints=web" - "traefik.http.routers.bethaus-app.entrypoints=web"
- "traefik.http.routers.bethaus-app.middlewares=redirect-to-https" - "traefik.http.routers.bethaus-app.middlewares=redirect-to-https"
# This is the "redirect-to-https" middleware definition
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
# ----------------------------------------------------- # HTTPS router (TLS via Let's Encrypt)
# HTTPS router: Listen on entrypoint "websecure"
# using TLS via your ACME (Let's Encrypt) resolver
# -----------------------------------------------------
- "traefik.http.routers.bethaus-app-secure.rule=Host(`app.bethaus-speyer.de`)" - "traefik.http.routers.bethaus-app-secure.rule=Host(`app.bethaus-speyer.de`)"
- "traefik.http.routers.bethaus-app-secure.entrypoints=websecure" - "traefik.http.routers.bethaus-app-secure.entrypoints=websecure"
- "traefik.http.routers.bethaus-app-secure.tls=true" - "traefik.http.routers.bethaus-app-secure.tls=true"
- "traefik.http.routers.bethaus-app-secure.tls.certresolver=myresolver" - "traefik.http.routers.bethaus-app-secure.tls.certresolver=myresolver"
# The services internal port # Internal port
- "traefik.http.services.bethaus-app.loadbalancer.server.port=5000" - "traefik.http.services.bethaus-app.loadbalancer.server.port=5000"
# Production-ready Gunicorn command with eventlet
command: > command: >
sh -c "pip install -r requirements.txt && flask run" sh -c "pip install -r requirements.txt &&
gunicorn --worker-class eventlet -w 1 -b 0.0.0.0:5000 app:app"
networks: networks:
traefik: traefik:
external: true external: true

View File

@ -3,3 +3,5 @@ flask_socketio
pillow pillow
diskcache diskcache
geoip2 geoip2
gunicorn
eventlet

View File

@ -53,33 +53,27 @@
<!-- Socket.IO client library --> <!-- Socket.IO client library -->
<script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script> <script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
<!-- Using vanilla JavaScript for dynamic DOM updates -->
<script> <script>
const socket = io(); const socket = io();
// Request initial data immediately on connection
socket.on('connect', () => {
socket.emit('request_initial_data');
});
socket.on('recent_connections', function(data) { socket.on('recent_connections', function(data) {
const tbody = document.getElementById('connectionsTableBody'); const tbody = document.getElementById('connectionsTableBody');
tbody.innerHTML = ''; // Clear previous content tbody.innerHTML = ''; // Clear previous content
data.forEach(record => { data.forEach(record => {
const row = document.createElement('tr'); const row = document.createElement('tr');
row.innerHTML = `
const timestampCell = document.createElement('td'); <td>${record.timestamp}</td>
timestampCell.textContent = record.timestamp; <td>${record.full_path}</td>
const fullPathCell = document.createElement('td'); <td>${record.ip_address}</td>
fullPathCell.textContent = record.full_path; <td>${record.user_agent}</td>
const ipCell = document.createElement('td'); <td>${record.referrer}</td>
ipCell.textContent = record.ip_address; `;
const userAgentCell = document.createElement('td');
userAgentCell.textContent = record.user_agent;
const referrerCell = document.createElement('td');
referrerCell.textContent = record.referrer;
row.appendChild(timestampCell);
row.appendChild(fullPathCell);
row.appendChild(ipCell);
row.appendChild(userAgentCell);
row.appendChild(referrerCell);
tbody.appendChild(row); tbody.appendChild(row);
}); });
}); });