
Транскрипция на живо, когато защитната стена блокира WebSocket-ите
Корпоративните мрежи обожават да разрешават HTTPS и тихо да убиват WebSocket upgrade-ите. Това счупва безшумно транскрипцията в реално време. GeekBye v2.0.8 автоматично преминава към чист HTTPS транспорт — а пускането му разкри бъг, който щеше да направи цялата функция безполезна.
Има един конкретен, влудяващ начин, по който транскрипцията в реално време се проваля в корпоративна мрежа. Wi-Fi-ят ти е наред. HTTPS работи — можеш да заредиш всеки сайт. Но транскрипцията на живо просто... не тръгва, и нищо не ти казва защо.
Виновникът е клас корпоративни proxy-та, които разрешават обикновения HTTPS трафик, но блокират WebSocket upgrade-а — handshake-а, който превръща една HTTPS връзка в постоянния, двупосочен канал, от който транскрипцията в реално време има нужда. За proxy-то WebSocket изглежда като немониториран тунел навън от мрежата, така че го убива. За теб транскрипцията е безшумно счупена.
GeekBye v2.0.8 добави автоматичен fallback точно за това — и изграждането му извади наяве бъг, който щеше да накара цялата функция да не прави нищо.
Защо fallback, а не просто retry
Вече се справяме с нестабилни мрежи. Ако връзката ти падне по средата на сесия, GeekBye се свързва отново с backoff и буферира аудиото ти, така че нищо да не се губи — това е отделна функция, разгледана в защо твоят AI notetaker спира при лош Wi-Fi.
Но блокиран WebSocket не е нестабилна връзка. Повторното опитване на същия WebSocket срещу proxy, който отказва WebSocket-ите, се проваля по същия начин всеки път, завинаги. Единственото решение е различен транспорт — такъв, който изглежда като обикновения HTTPS, който proxy-то вече разрешава.
Затова v2.0.8 преминава към чист HTTPS транспорт през същия автентикиран endpoint:
- Надолу (транскрипциите, идващи обратно към теб): server-sent events — дълготраен HTTPS отговор, който proxy-то вижда като обикновено стриймвано изтегляне.
- Нагоре (аудиото ти, което излиза): групирани POST заявки, всяка носеща парче аудио с пореден номер, така че сървърът да може да ги сглоби в правилния ред, дори ако мрежата ги пренареди.
Никакъв постоянен socket, нищо, което да изглежда като тунел — само HTTPS заявки и отговори. Ако proxy ти позволява да ползваш сайт, позволява и това.
Бъгът, който щеше да пусне мъртва функция
Ето частта, която си струва да прочетеш. Fallback-ът трябва да се задейства, когато WebSocket връзката изчерпи опитите си със сигнатура на блокиран транспорт — всеки опит се проваля на upgrade-а, никакъв auth или quota проблем, поне един отказ с форма на proxy. Proxy, който блокира WebSocket, обикновено отговаря на upgrade-а с HTTP 403 Forbidden или 407.
Проблемът: кодът ни за свързване вече имаше правило, че 403 означава фатална грешка при автентикация — спри, покажи я на потребителя, не опитвай отново. Което е правилно почти навсякъде. Но означаваше, че 403-ката от блокиращ proxy — точно сигналът, който трябваше да задейства fallback-а — вместо това се хвърляше като фатална грешка преди логиката за fallback изобщо да може да се изпълни. Само чисто падане на връзката (затваряне с 1006) стигаше до fallback-а. Така функцията щеше да работи за редкия случай и безшумно да се проваля за реалната си основна цел: корпоративния proxy.
Хванахме това, докато калявахме изданието, не в продукция. Фиксът: 403/407 на upgrade участъка на WebSocket сега се третира като възстановим, така че циклусът на свързване да може да се изчерпи до fallback — докато истински провал при автентикация (който пристига различно, след като upgrade-ът успее) все така се проваля бързо, точно както преди. Регресионен тест сега фиксира разграничението: 403 от блокиращ proxy трябва да мине на fallback; истинска auth 403 не трябва.
Останалата част от каляването следваше същата параноична линия: timeout на всеки POST нагоре, така че proxy, което приема заявка, но никога не отговаря, да не може да задръсти аудио потока, и гаранция, че истински проблем със sign-in никога не може да бъде безшумно замаскиран от механизма за fallback.
Тествахме го срещу реален враждебен proxy
Функция, чиято цялостна цел е оцеляване във враждебни мрежи, не може да бъде валидирана само с unit тестове — unit тестовете нямат proxy-та. Преди да я активираме, прекарахме реалното приложение през локален reverse proxy, конфигуриран да прави точно това, което правят корпоративните proxy-та: препраща HTTPS, отхвърля WebSocket upgrade-ите с 403.
Следата в логовете е разписката: четири блокирани WebSocket опита, разпозната сигнатура на изчерпване, автоматично превключване към HTTPS транспорта, и после здрава 96-секундна сесия за транскрипция през чист HTTPS — 66 транскрипт сегмента, нулеви загуби. Failover-ът работи, защото го гледахме как превключва.
Три преносими урока
- „Работи при лош Wi-Fi" и „работи зад враждебен proxy" са различни гаранции. Едното има нужда от повторно свързване; другото има нужда от различен транспорт. Смесването им оставя цяла популация корпоративни потребители безшумно счупени.
- Твоята класификация на грешки може да скрие собствената ти функция от самата нея. Правило, което е правилно 99% от времето (403 = фатален auth), беше точно грешно за 1%-те, заради които тази функция съществуваше. Когато добавяш fallback, провери дали условието за задействане изобщо може да достигне до fallback-а.
- Тествай противника, не само щастливия път. Единственият честен тест за „оцелява срещу proxy, който блокира WebSocket-ите", е proxy, който блокира WebSocket-ите. Построихме такъв.
GeekBye v2.0.8 пусна HTTPS fallback-а зад флаг и валидиран. За работата по надеждността, до която стои, виж защо твоят AI notetaker спира при лош Wi-Fi, а за съседните издания в тази серия — защо твоят AI notetaker спира записа по средата на срещата (v2.0.9) и защо AI транскрипцията греши техническите термини (v2.0.11).