
Transcriere live când firewall-ul blochează WebSocket-urile
Rețelele corporate adoră să permită HTTPS și să omoare discret upgrade-urile WebSocket. Asta strică în tăcere transcrierea în timp real. GeekBye v2.0.8 trece automat pe un transport pur-HTTPS — iar livrarea lui a scos la iveală un bug care ar fi făcut întreaga funcție inutilă.
Există un mod anume, exasperant, în care transcrierea în timp real eșuează pe o rețea corporate. Wi-Fi-ul tău e în regulă. HTTPS merge — poți încărca orice site. Dar transcrierea live pur și simplu... nu pornește, și nimic nu-ți spune de ce.
Vinovatul e o categorie de proxy corporate care permite traficul HTTPS obișnuit dar blochează upgrade-ul WebSocket — handshake-ul care transformă o conexiune HTTPS în canalul persistent, bidirecțional de care are nevoie transcrierea în timp real. Pentru proxy, un WebSocket arată ca un tunel nemonitorizat de ieșire din rețea, așa că îl omoară. Pentru tine, transcrierea e stricată în tăcere.
GeekBye v2.0.8 a adăugat un fallback automat exact pentru asta — iar construirea lui a scos la iveală un bug care ar fi făcut ca întreaga funcție să nu facă nimic.
De ce un fallback, nu doar un retry
Gestionăm deja rețelele instabile. Dacă îți cade conexiunea în mijlocul sesiunii, GeekBye se reconectează cu backoff și îți tamponează audio-ul ca să nu se piardă nimic — asta e o funcție separată acoperită în de ce notetaker-ul tău AI se oprește pe Wi-Fi prost.
Dar un WebSocket blocat nu e o conexiune instabilă. Reîncercarea aceluiași WebSocket împotriva unui proxy care refuză WebSocket-urile eșuează la fel de fiecare dată, la nesfârșit. Singura soluție e un transport diferit — unul care arată ca simplul HTTPS pe care proxy-ul îl permite deja.
Așa că v2.0.8 trece pe un transport pur-HTTPS peste același endpoint autentificat:
- La coborâre (transcrierile care vin înapoi la tine): server-sent events — un răspuns HTTPS de lungă durată pe care proxy-ul îl vede ca un download obișnuit, în flux.
- La urcare (audio-ul tău care iese): cereri POST grupate, fiecare purtând un fragment de audio cu un număr de secvență, ca serverul să le poată reasambla în ordine chiar dacă rețeaua le reordonează.
Niciun socket persistent, nimic care să arate ca un tunel — doar cereri și răspunsuri HTTPS. Dacă un proxy îți permite să folosești un site, permite și asta.
Bug-ul care ar fi livrat o funcție moartă
Iată partea care merită citită. Fallback-ul ar trebui să se declanșeze când conexiunea WebSocket își epuizează încercările cu o semnătură de transport blocat — fiecare încercare eșuând la upgrade, nicio problemă de autentificare sau de cotă, cel puțin un refuz cu formă de proxy. Un proxy care blochează un WebSocket răspunde de obicei la upgrade cu un HTTP 403 Forbidden sau 407.
Problema: codul nostru de conexiune avea deja o regulă că un 403 înseamnă eroare fatală de autentificare — oprește, adu-o în fața utilizatorului, nu reîncerca. Ceea ce e corect aproape peste tot. Dar însemna că 403-ul de la un proxy blocant — exact semnalul care ar fi trebuit să declanșeze fallback-ul — era în schimb aruncat ca eroare fatală înainte ca logica de fallback să poată rula vreodată. Doar o cădere brută de conexiune (o închidere 1006) ajungea până la fallback. Deci funcția ar fi mers pentru cazul rar și ar fi eșuat în tăcere pentru ținta ei principală reală: proxy-ul corporate.
Am prins asta în timp ce întăream lansarea, nu în producție. Fixul: un 403/407 pe segmentul de upgrade WebSocket e acum tratat ca recuperabil, ca bucla de conexiune să se poată epuiza în fallback — în timp ce un eșec real de autentificare (care sosește diferit, după ce upgrade-ul reușește) eșuează în continuare rapid, exact ca înainte. Un test de regresie fixează acum distincția: un 403 de la proxy blocant trebuie să treacă pe fallback; un 403 real de autentificare nu trebuie.
Restul întăririi a urmat aceeași linie paranoică: un timeout pe fiecare POST de urcare, ca un proxy care acceptă o cerere dar nu răspunde niciodată să nu poată bloca fluxul audio, și o garanție că o problemă reală de sign-in nu poate fi niciodată mascată în tăcere de mașinăria de fallback.
Am testat împotriva unui proxy ostil real
O funcție al cărei întreg scop e supraviețuirea rețelelor ostile nu poate fi validată doar prin teste unitare — testele unitare nu au proxy-uri. Înainte s-o activăm, am rulat aplicația reală printr-un reverse proxy local configurat să facă exact ce fac proxy-urile corporate: forwardează HTTPS, respinge upgrade-urile WebSocket cu un 403.
Urma din log-uri e chitanța: patru încercări WebSocket blocate, semnătura de epuizare recunoscută, comutarea automată pe transportul HTTPS, și apoi o sesiune sănătoasă de transcriere de 96 de secunde peste pur HTTPS — 66 de segmente de transcript, zero pierderi. Failover-ul merge pentru că l-am privit cum trece.
Trei lecții transferabile
- „Merge pe Wi-Fi prost" și „merge în spatele unui proxy ostil" sunt garanții diferite. Una are nevoie de reconectare; cealaltă are nevoie de un transport diferit. Confundarea lor lasă o întreagă populație de utilizatori corporate stricată în tăcere.
- Clasificarea ta de erori îți poate ascunde propria funcție de ea însăși. O regulă corectă în 99% din cazuri (403 = auth fatal) era exact greșită pentru cei 1% pentru care exista această funcție. Când adaugi un fallback, auditează dacă condiția de declanșare poate măcar ajunge la fallback.
- Testează adversarul, nu doar drumul fericit. Singurul test onest pentru „supraviețuiește unui proxy care blochează WebSocket-urile" e un proxy care blochează WebSocket-urile. Am construit unul.
GeekBye v2.0.8 a livrat fallback-ul HTTPS controlat prin flag și validat. Pentru munca de fiabilitate alături de care stă, vezi de ce notetaker-ul tău AI se oprește pe Wi-Fi prost, iar pentru lansările vecine din această serie, de ce notetaker-ul tău AI oprește înregistrarea în mijlocul ședinței (v2.0.9) și de ce transcrierea AI înțelege greșit termenii tehnici (v2.0.11).