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

76
app.py
View File

@ -10,7 +10,7 @@ import diskcache
import threading
import json
import time
from flask_socketio import SocketIO
from flask_socketio import SocketIO, emit
import geoip2.database
from functools import lru_cache
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('/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
clients_connected = 0
@ -312,41 +313,40 @@ def crawl_and_cache(subpath):
return json.dumps({"cached_files": cached_files}, indent=4), 200
def query_recent_connections():
global clients_connected
last_connections = None # Initialize with None to ensure the first emit happens
while clients_connected > 0:
rows = a.return_file_access()
global clients_connected, background_thread_running
background_thread_running = True
last_connections = None
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.
connections = [
{
'timestamp': row[0],
'full_path': row[1],
'ip_address': row[2],
'user_agent': row[3],
'referrer': row[4]
}
for row in rows
]
if connections != last_connections:
socketio.emit('recent_connections', connections)
last_connections = connections.copy()
# Only emit if there's a change compared to the previous connections.
if connections != last_connections:
socketio.emit('recent_connections', connections)
last_connections = connections.copy() # Store a copy of the current state
time.sleep(1)
print("No clients connected; stopping query thread.")
socketio.sleep(1)
finally:
background_thread_running = False
print("No clients connected; stopping query thread.")
@socketio.on('connect')
def handle_connect():
global clients_connected, background_thread
def handle_connect(auth=None):
global clients_connected, background_thread_running
clients_connected += 1
print("Client connected. Total clients:", clients_connected)
with thread_lock:
# Start the background task if it's not already running.
if background_thread is None or not background_thread.is_alive():
background_thread = socketio.start_background_task(query_recent_connections)
if not background_thread_running:
socketio.start_background_task(query_recent_connections)
print("Started background query task.")
@socketio.on('disconnect')
@ -355,6 +355,20 @@ def handle_disconnect():
clients_connected -= 1
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.
@app.route('/', defaults={'path': ''})
@ -363,5 +377,5 @@ def handle_disconnect():
def index(path):
return render_template("app.html")
if __name__ == '__main__':
if __name__ == '__main__':
socketio.run(app, debug=True, host='0.0.0.0')

View File

@ -16,40 +16,32 @@ services:
propagation: rshared
environment:
- FLASK_APP=app.py
- FLASK_RUN_HOST=0.0.0.0
- FLASK_ENV=production
networks:
- traefik
labels:
- "traefik.enable=true"
# ----------------------------------------------------
# HTTP router: Listen on entrypoint "web" (port 80)
# and apply a middleware to force redirect to HTTPS
# ----------------------------------------------------
# HTTP router (port 80), redirecting to HTTPS
- "traefik.http.routers.bethaus-app.rule=Host(`app.bethaus-speyer.de`)"
- "traefik.http.routers.bethaus-app.entrypoints=web"
- "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"
# -----------------------------------------------------
# HTTPS router: Listen on entrypoint "websecure"
# using TLS via your ACME (Let's Encrypt) resolver
# -----------------------------------------------------
# HTTPS router (TLS via Let's Encrypt)
- "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.tls=true"
- "traefik.http.routers.bethaus-app-secure.tls.certresolver=myresolver"
# The services internal port
# Internal port
- "traefik.http.services.bethaus-app.loadbalancer.server.port=5000"
# Production-ready Gunicorn command with eventlet
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:
traefik:
external: true

View File

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

View File

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