Update dependencies and enhance WebSocket server logging: Add 'chrono' and 'android_system_properties' to Cargo.lock, improve error handling and logging in websocket_server.rs, and streamline character creation notifications in worker modules for better clarity and maintainability.
This commit is contained in:
@@ -20,10 +20,8 @@ use tokio_rustls::rustls::{self, ServerConfig};
|
||||
use tokio_rustls::TlsAcceptor;
|
||||
use tokio_tungstenite::tungstenite::Message;
|
||||
use tokio_tungstenite::accept_async;
|
||||
use rustls_pemfile::{certs, ec_private_keys, pkcs8_private_keys, rsa_private_keys};
|
||||
use rustls::pki_types::{
|
||||
CertificateDer, PrivateKeyDer, PrivatePkcs1KeyDer, PrivatePkcs8KeyDer, PrivateSec1KeyDer,
|
||||
};
|
||||
use rustls_pemfile::{certs, pkcs8_private_keys, rsa_private_keys};
|
||||
use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs1KeyDer, PrivatePkcs8KeyDer};
|
||||
|
||||
/// Einfacher WebSocket-Server auf Basis von Tokio + tokio-tungstenite.
|
||||
///
|
||||
@@ -134,7 +132,7 @@ fn create_tls_acceptor(
|
||||
let key_file = File::open(key_path)?;
|
||||
let mut key_reader = BufReader::new(key_file);
|
||||
|
||||
// Versuche zuerst PKCS8, dann ggf. RSA-Key, dann SEC1 (EC PRIVATE KEY).
|
||||
// Versuche zuerst PKCS8, dann ggf. RSA-Key
|
||||
let mut keys: Vec<PrivateKeyDer<'static>> = pkcs8_private_keys(&mut key_reader)
|
||||
.map(|res: Result<PrivatePkcs8KeyDer<'static>, _>| res.map(PrivateKeyDer::Pkcs8))
|
||||
.collect::<Result<_, _>>()?;
|
||||
@@ -149,16 +147,7 @@ fn create_tls_acceptor(
|
||||
}
|
||||
|
||||
if keys.is_empty() {
|
||||
// Leser zurücksetzen und SEC1 (EC PRIVATE KEY) versuchen
|
||||
let key_file = File::open(key_path)?;
|
||||
let mut key_reader = BufReader::new(key_file);
|
||||
keys = ec_private_keys(&mut key_reader)
|
||||
.map(|res: Result<PrivateSec1KeyDer<'static>, _>| res.map(PrivateKeyDer::Sec1))
|
||||
.collect::<Result<_, _>>()?;
|
||||
}
|
||||
|
||||
if keys.is_empty() {
|
||||
return Err("Key-Datei enthält keinen privaten Schlüssel (PKCS8, RSA oder SEC1)".into());
|
||||
return Err("Key-Datei enthält keinen privaten Schlüssel (PKCS8 oder RSA)".into());
|
||||
}
|
||||
|
||||
let private_key = keys.remove(0);
|
||||
@@ -210,6 +199,7 @@ impl WebSocketServer {
|
||||
"Starte WebSocket-Server auf Port {} mit SSL (cert: {:?}, key: {:?})",
|
||||
self.port, self.cert_path, self.key_path
|
||||
);
|
||||
// Hinweis: SSL-Unterstützung ist noch nicht implementiert.
|
||||
} else {
|
||||
println!("Starte WebSocket-Server auf Port {} (ohne SSL)", self.port);
|
||||
}
|
||||
@@ -238,22 +228,15 @@ impl WebSocketServer {
|
||||
self.cert_path.as_deref(),
|
||||
self.key_path.as_deref(),
|
||||
) {
|
||||
Ok(acc) => {
|
||||
println!("[WebSocketServer] TLS erfolgreich initialisiert. Server akzeptiert wss:// Verbindungen.");
|
||||
Some(acc)
|
||||
}
|
||||
Ok(acc) => Some(acc),
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
"[WebSocketServer] TLS-Initialisierung fehlgeschlagen, starte ohne SSL: {err}"
|
||||
);
|
||||
eprintln!(
|
||||
"[WebSocketServer] ACHTUNG: WEBSOCKET_SSL_ENABLED=true, aber TLS ist nicht aktiv. Clients müssen dann ws:// statt wss:// verwenden."
|
||||
);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("[WebSocketServer] TLS deaktiviert. Server akzeptiert nur ws:// Verbindungen (nicht wss://).");
|
||||
None
|
||||
};
|
||||
|
||||
@@ -304,76 +287,48 @@ async fn run_accept_loop(
|
||||
tls_acceptor: Option<TlsAcceptor>,
|
||||
) {
|
||||
let listener = match TcpListener::bind(&addr).await {
|
||||
Ok(l) => {
|
||||
println!("[WebSocketServer] Erfolgreich gebunden an {}", addr);
|
||||
l
|
||||
}
|
||||
Ok(l) => l,
|
||||
Err(e) => {
|
||||
eprintln!("[WebSocketServer] FEHLER: Konnte nicht an {} binden: {}", addr, e);
|
||||
eprintln!("[WebSocketServer] Mögliche Ursachen: Port bereits belegt, keine Berechtigung, oder Firewall blockiert.");
|
||||
eprintln!("[WebSocketServer] Fehler beim Binden an {}: {}", addr, e);
|
||||
running.store(false, Ordering::SeqCst);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
println!("[WebSocketServer] Lauscht auf {} (TLS: {})", addr, tls_acceptor.is_some());
|
||||
|
||||
// Heartbeat: Logge regelmäßig, dass der Server läuft
|
||||
let mut heartbeat_interval = interval(TokioDuration::from_secs(300)); // Alle 5 Minuten
|
||||
let server_start = std::time::Instant::now();
|
||||
println!("[WebSocketServer] Lauscht auf {}", addr);
|
||||
|
||||
while running.load(Ordering::SeqCst) {
|
||||
tokio::select! {
|
||||
// Heartbeat: Logge alle 5 Minuten, dass der Server läuft
|
||||
_ = heartbeat_interval.tick() => {
|
||||
let uptime = server_start.elapsed().as_secs();
|
||||
println!("[WebSocketServer] Heartbeat: Server läuft seit {} Sekunden auf {} (TLS: {})",
|
||||
uptime, addr, tls_acceptor.is_some());
|
||||
let (stream, peer) = match listener.accept().await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
eprintln!("[WebSocketServer] accept() fehlgeschlagen: {}", e);
|
||||
continue;
|
||||
}
|
||||
// Neue Verbindung akzeptieren
|
||||
result = listener.accept() => {
|
||||
match result {
|
||||
Ok((stream, peer)) => {
|
||||
let peer_addr = peer;
|
||||
println!("[WebSocketServer] Client-Verbindungsversuch von {} (TCP-Verbindung etabliert)", peer_addr);
|
||||
|
||||
let rx = tx.subscribe();
|
||||
let registry_clone = registry.clone();
|
||||
let ws_log_clone = ws_log.clone();
|
||||
let tls_acceptor_clone = tls_acceptor.clone();
|
||||
};
|
||||
|
||||
tokio::spawn(async move {
|
||||
if let Some(acc) = tls_acceptor_clone {
|
||||
println!("[WebSocketServer] Starte TLS-Handshake für {}...", peer_addr);
|
||||
match acc.accept(stream).await {
|
||||
Ok(tls_stream) => {
|
||||
println!("[WebSocketServer] TLS-Handshake erfolgreich für {}", peer_addr);
|
||||
handle_connection(tls_stream, peer_addr, rx, registry_clone, ws_log_clone)
|
||||
.await
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
"[WebSocketServer] TLS-Handshake fehlgeschlagen ({peer_addr}): {err}"
|
||||
);
|
||||
eprintln!(
|
||||
"[WebSocketServer] Mögliche Ursachen: Ungültiges Zertifikat, unsupported Cipher, oder Client verwendet ws:// statt wss://"
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("[WebSocketServer] Verarbeite Verbindung von {} ohne TLS (Client sollte ws:// verwenden, nicht wss://)", peer_addr);
|
||||
handle_connection(stream, peer_addr, rx, registry_clone, ws_log_clone).await;
|
||||
}
|
||||
});
|
||||
let peer_addr = peer;
|
||||
let rx = tx.subscribe();
|
||||
let registry_clone = registry.clone();
|
||||
let ws_log_clone = ws_log.clone();
|
||||
let tls_acceptor_clone = tls_acceptor.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
if let Some(acc) = tls_acceptor_clone {
|
||||
match acc.accept(stream).await {
|
||||
Ok(tls_stream) => {
|
||||
handle_connection(tls_stream, peer_addr, rx, registry_clone, ws_log_clone)
|
||||
.await
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("[WebSocketServer] Fehler beim Akzeptieren einer Verbindung: {}", e);
|
||||
// Kurz warten, um CPU-Last zu reduzieren bei wiederholten Fehlern
|
||||
tokio::time::sleep(TokioDuration::from_millis(100)).await;
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
"[WebSocketServer] TLS-Handshake fehlgeschlagen ({peer_addr}): {err}"
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handle_connection(stream, peer_addr, rx, registry_clone, ws_log_clone).await;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,19 +341,16 @@ async fn handle_connection<S>(
|
||||
) where
|
||||
S: AsyncRead + AsyncWrite + Unpin + Send + 'static,
|
||||
{
|
||||
println!("[WebSocketServer] Versuche WebSocket-Handshake für {}...", peer_addr);
|
||||
let ws_stream = match accept_async(stream).await {
|
||||
Ok(ws) => {
|
||||
println!("[WebSocketServer] WebSocket-Handshake erfolgreich für {} - Verbindung etabliert", peer_addr);
|
||||
ws
|
||||
}
|
||||
Ok(ws) => ws,
|
||||
Err(e) => {
|
||||
eprintln!("[WebSocketServer] WebSocket-Handshake fehlgeschlagen ({peer_addr}): {e}");
|
||||
eprintln!("[WebSocketServer] Mögliche Ursachen: Client sendet kein WebSocket-Request, falscher Upgrade-Header, oder Protokoll-Mismatch");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
println!("[WebSocketServer] Neue Verbindung von {}", peer_addr);
|
||||
|
||||
let (mut ws_sender, mut ws_receiver) = ws_stream.split();
|
||||
|
||||
// Kanal für Antworten direkt an diesen Client (z.B. getConnections)
|
||||
|
||||
Reference in New Issue
Block a user