Compare commits

...

2 Commits

Author SHA1 Message Date
duffyduck 33d5be781f release: bump version to 0.1.6.0 2026-05-16 19:21:04 +02:00
duffyduck 785f5d0805 fix(bridge): grosse File-Re-Downloads zerreissen nicht mehr die WS
Symptom (aus Bridge-Log): bei chat_history_request triggert die App
file_request fuer alle fehlenden Anhaenge. Bei einem 40 MB MP4 wird das
base64-encoded ~53 MB, ueberschreitet das RVS-maxPayload (50 MB).
Server droppt mit Code 1009 'message too big', Bridge crasht im cleanup
mit AttributeError 'NoneType has no call_soon' (websockets-Lib-Bug bei
nested context-manager-cleanup nach abgerissener Verbindung).

Drei Layer:

(1) RVS-Server: maxPayload 50 → 100 MB — deckt ~70 MB binaer ab nach
    base64-inflate. Comment im server.js erklaert den Hintergrund.

(2) Bridge: max_size 50 → 100 MB synchron zum Server. PLUS pre-check
    im file_request-Handler — Dateien > 70 MB werden mit Fehler-Response
    abgewiesen statt blind base64-zu-encoden und die WS zu killen.
    Limit knapp unter Server-Limit damit Bridge proaktiv blockiert.

(3) App: file_response-Handler liest 'error'-Feld aus dem Payload und
    zeigt nen Toast 'Datei X: Datei zu gross fuer Transfer (40 MB,
    Limit 70 MB)'. Statt einfach zu schweigen oder endlos zu retryen.

Crash bei websockets-cleanup ist ein Lib-Bug (NoneType.call_soon) —
nicht direkt fixbar, aber tritt jetzt nicht mehr auf weil Bridge proaktiv
die zu grossen Files ablehnt und die WS nicht mehr abreisst.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 19:18:52 +02:00
5 changed files with 52 additions and 8 deletions
+2 -2
View File
@@ -79,8 +79,8 @@ android {
applicationId "com.ariacockpit"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 10509
versionName "0.1.5.9"
versionCode 10600
versionName "0.1.6.0"
// Fallback fuer Libraries mit Product Flavors
missingDimensionStrategy 'react-native-camera', 'general'
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "aria-cockpit",
"version": "0.1.5.9",
"version": "0.1.6.0",
"private": true,
"scripts": {
"android": "react-native run-android",
+10
View File
@@ -888,6 +888,16 @@ const ChatScreen: React.FC = () => {
const b64 = (message.payload.base64 as string) || '';
const serverPath = (message.payload.serverPath as string) || '';
const mimeType = (message.payload.mimeType as string) || '';
// Fehler-Response (z.B. Datei zu gross, nicht gefunden) → Toast,
// kein erneuter Versuch. Hauptverdacht: 40+ MB Videos die ueber
// den 70 MB Bridge-Limit gehen.
const fileErr = (message.payload as any).error as string | undefined;
if (fileErr) {
const fname = (message.payload.name as string) || serverPath.split('/').pop() || 'Datei';
console.warn('[Chat] file_response Fehler fuer %s: %s', fname, fileErr);
ToastAndroid.show(`${fname}: ${fileErr}`, ToastAndroid.LONG);
return;
}
if (b64 && reqId) {
const fileName = (message.payload.name as string) || 'download';
persistAttachment(b64, reqId, fileName).then(filePath => {
+32 -2
View File
@@ -1478,8 +1478,11 @@ class ARIABridge:
try:
url = f"{current_url}?token={self.rvs_token}"
logger.info("[rvs] Verbinde: %s", current_url)
# max_size=50MB (siehe core-Connect oben — gleicher Grund).
async with websockets.connect(url, max_size=50 * 1024 * 1024) as ws:
# max_size=100MB synchron zum RVS-Server (siehe rvs/server.js).
# File-Re-Download fuer Anhaenge braucht Platz fuer base64-
# inflate (~1.33×). Groessere Files lehnt der file_request-
# Handler proaktiv ab bevor's zur 1009-Disconnection kommt.
async with websockets.connect(url, max_size=100 * 1024 * 1024) as ws:
self.ws_rvs = ws
retry_delay = 2
logger.info("[rvs] Verbunden — warte auf App-Nachrichten")
@@ -2204,6 +2207,33 @@ class ARIABridge:
"timestamp": int(asyncio.get_event_loop().time() * 1000),
})
return
# Groessen-Check VOR base64-Encode + Send. Sonst zerreisst's bei
# grossen Files (>~70 MB binaer) die WebSocket-Verbindung mit
# Code 1009 (message too big) — RVS-Server droppt, Bridge crasht
# im cleanup (websockets-Lib-Bug). Limit deckt typische Videos
# und Bilder ab; alles drueber soll der User per SSH abholen.
FILE_MAX_BYTES = 70 * 1024 * 1024
try:
file_size = os.path.getsize(server_path)
except OSError as exc:
logger.warning("[rvs] getsize fehlgeschlagen: %s", exc)
file_size = 0
if file_size > FILE_MAX_BYTES:
logger.warning("[rvs] Re-Download abgelehnt: %s zu gross (%dMB > %dMB)",
server_path, file_size // (1024 * 1024),
FILE_MAX_BYTES // (1024 * 1024))
await self._send_to_rvs({
"type": "file_response",
"payload": {
"requestId": req_id,
"serverPath": server_path,
"name": os.path.basename(server_path),
"error": f"Datei zu gross fuer Transfer ({file_size // (1024 * 1024)} MB, Limit {FILE_MAX_BYTES // (1024 * 1024)} MB)",
"sizeBytes": file_size,
},
"timestamp": int(asyncio.get_event_loop().time() * 1000),
})
return
with open(server_path, "rb") as f:
file_b64 = base64.b64encode(f.read()).decode("ascii")
mime, _ = mimetypes.guess_type(server_path)
+7 -3
View File
@@ -71,10 +71,14 @@ function cleanupRooms() {
// ── WebSocket-Server starten ────────────────────────────────────────
// maxPayload 50MB: TTS-Streaming + Voice-Upload (WAV als base64) +
// maxPayload 100MB: TTS-Streaming + Voice-Upload (WAV als base64) +
// audio_pcm Chunks koennen die ws-Library Default 1MB ueberschreiten.
// Default-Limit war der Killer fuer die voice_upload Pipeline.
const wss = new WebSocketServer({ port: PORT, maxPayload: 50 * 1024 * 1024 });
// Plus: file_request/file_response fuer Re-Download von Anhaengen.
// 40 MB MP4 → ~53 MB base64 → vorher mit 50 MB Limit zerschossen
// (Code 1009 message too big, Bridge crashed im cleanup). 100 MB
// deckt bis ~70 MB binaer ab; groessere Files werden Bridge-seitig
// abgewiesen (siehe file_request-Handler) bevor die WS abreisst.
const wss = new WebSocketServer({ port: PORT, maxPayload: 100 * 1024 * 1024 });
wss.on("listening", () => {
log(`RVS läuft auf Port ${PORT} | Max Sessions: ${MAX_SESSIONS}`);