Steven
Steven3 นาทีที่อ่าน

เมื่อไฟร์วอลล์บล็อก WebSocket แล้วการถอดเสียงเรียลไทม์จะเป็นยังไง

เครือข่ายองค์กรชอบปล่อย HTTPS ให้ผ่าน แต่แอบฆ่า WebSocket upgrade ทิ้งเงียบๆ ซึ่งทำให้การถอดเสียงเรียลไทม์พังแบบไร้เสียง GeekBye v2.0.8 จะ fall back ไปยัง transport แบบ HTTPS ล้วนโดยอัตโนมัติ — และระหว่างที่ทำมันออกมา เราก็เจอบั๊กที่จะทำให้ทั้งฟีเจอร์นี้ไร้ประโยชน์ไปเลย

ถอดเสียง
เครือข่าย
วิศวกรรม
GeekBye Releases
เมื่อไฟร์วอลล์บล็อก WebSocket แล้วการถอดเสียงเรียลไทม์จะเป็นยังไง

มีวิธีล้มเหลวแบบเจาะจงและน่าหัวเสียอยู่แบบหนึ่ง ที่การถอดเสียงเรียลไทม์จะเจอบนเครือข่ายองค์กร Wi-Fi ของคุณก็ปกติดี HTTPS ก็ใช้ได้ — เปิดเว็บไหนก็ได้ แต่การถอดเสียงสดกลับ…ไม่ยอมเริ่ม และไม่มีอะไรบอกคุณเลยว่าทำไม

ตัวการคือ proxy องค์กรประเภทหนึ่งที่ปล่อยทราฟฟิก HTTPS ธรรมดาให้ผ่าน แต่บล็อก WebSocket upgrade — คือ handshake ที่เปลี่ยนการเชื่อมต่อ HTTPS ให้กลายเป็นช่องทางสองทางแบบถาวรที่การถอดเสียงเรียลไทม์ต้องใช้ ในสายตา proxy WebSocket ดูเหมือนอุโมงค์ที่ไม่ถูกตรวจสอบซึ่งพุ่งออกนอกเครือข่าย มันเลยฆ่าทิ้ง ส่วนในสายตาคุณ การถอดเสียงก็แค่พังไปเงียบๆ

GeekBye v2.0.8 เพิ่ม fallback อัตโนมัติสำหรับกรณีนี้โดยเฉพาะ — และการสร้างมันขึ้นมาก็ทำให้เจอบั๊กที่จะทำให้ทั้งฟีเจอร์ไม่ทำอะไรเลย

ทำไมต้อง fallback ไม่ใช่แค่ retry

เน็ตกระตุกๆ เราจัดการอยู่แล้ว ถ้าการเชื่อมต่อหลุดกลางเซสชัน GeekBye จะ reconnect แบบมี backoff และ buffer เสียงของคุณไว้ให้ไม่มีอะไรหาย — นั่นเป็นอีกฟีเจอร์หนึ่ง อ่านได้ที่ทำไม AI notetaker ของคุณถึงหยุดเมื่อ Wi-Fi ห่วย

แต่ WebSocket ที่ถูกบล็อกไม่ใช่การเชื่อมต่อที่กระตุก การ retry WebSocket ตัวเดิมกับ proxy ที่ปฏิเสธ WebSocket ก็ล้มเหลวแบบเดิมทุกครั้ง ตลอดไป ทางแก้เดียวคือ transport คนละแบบ — แบบที่ดูเหมือน HTTPS ธรรมดาที่ proxy อนุญาตอยู่แล้ว

ดังนั้น v2.0.8 จึง fall back ไปยัง transport แบบ HTTPS ล้วน บน endpoint เดิมที่ยืนยันตัวตนแล้ว:

  • ขาลง (ผลถอดเสียงที่ส่งกลับมาหาคุณ): server-sent events — HTTPS response อายุยาวที่ proxy มองว่าเป็นการดาวน์โหลดแบบ stream ธรรมดา
  • ขาขึ้น (เสียงของคุณที่ส่งออกไป): POST request แบบ batch แต่ละอันแบกเสียงชิ้นหนึ่งพร้อมหมายเลขลำดับ เพื่อให้เซิร์ฟเวอร์ประกอบกลับเรียงตามลำดับได้ แม้เครือข่ายจะสลับลำดับก็ตาม

ไม่มี socket ถาวร ไม่มีอะไรที่ดูเหมือนอุโมงค์ — มีแค่ request และ response แบบ HTTPS ถ้า proxy ยอมให้คุณใช้เว็บไซต์ได้ มันก็ยอมให้อันนี้ได้

บั๊กที่เกือบปล่อยฟีเจอร์ที่ตายแล้วออกไป

นี่คือส่วนที่คุ้มค่าจะอ่าน fallback ควรจะทำงานเมื่อการเชื่อมต่อ WebSocket ใช้ความพยายามจนหมดพร้อม signature ของการถูกบล็อก transport — คือทุกครั้งล้มเหลวที่ขั้น upgrade ไม่มีปัญหาเรื่อง auth หรือ quota และมีการปฏิเสธในรูปแบบของ proxy อย่างน้อยหนึ่งครั้ง proxy ที่บล็อก WebSocket มักตอบ upgrade กลับมาด้วย HTTP 403 Forbidden หรือ 407

ปัญหาคือ: โค้ดการเชื่อมต่อของเรามีกฎอยู่แล้วว่า 403 หมายถึง auth error ร้ายแรง — หยุด แล้วโยนให้ผู้ใช้เห็น อย่า retry ซึ่งถูกต้องแทบทุกที่ แต่มันแปลว่า 403 จาก proxy ตัวบล็อก — สัญญาณตัวเป๊ะๆ ที่ควรจะจุดชนวน fallback — กลับถูกโยนเป็น error ร้ายแรง ก่อนที่ logic ของ fallback จะได้มีโอกาสทำงานเสียอีก มีแต่การหลุดการเชื่อมต่อแบบดิบๆ (การปิดด้วย 1006) เท่านั้นที่รอดลงไปถึง fallback ฟีเจอร์นี้เลยจะทำงานได้กับกรณีที่เกิดยาก แต่ล้มเหลวเงียบๆ กับเป้าหมายหลักตัวจริงของมัน นั่นคือ proxy องค์กร

เราดักเจอตอนกำลังทำ release ให้แข็งแรง ไม่ใช่ตอนขึ้น production แล้ว วิธีแก้: 403/407 บนขา upgrade ของ WebSocket ตอนนี้ถูกถือว่ากู้คืนได้ เพื่อให้ loop การเชื่อมต่อใช้จนหมดแล้วตกลง fallback ได้ — ในขณะที่ความล้มเหลวของ auth ตัวจริง (ซึ่งมาถึงคนละแบบ หลังจาก upgrade สำเร็จแล้ว) ก็ยังล้มเหลวเร็วเหมือนเดิมเป๊ะ ตอนนี้มี regression test ตรึงความต่างนี้ไว้: 403 ของ proxy ตัวบล็อกต้อง fall back; 403 ของ auth ตัวจริงต้องไม่ fall back

การทำให้แข็งแรงส่วนที่เหลือก็เดินตามแนวขี้ระแวงเดียวกัน: ใส่ timeout ให้ทุก POST ขาขึ้น เพื่อไม่ให้ proxy ที่รับ request แต่ไม่ตอบกลับมาเลยมาทำให้ audio stream ค้าง และรับประกันว่าปัญหา sign-in ตัวจริงจะไม่มีวันถูกกลไก fallback บดบังไปแบบเงียบๆ

เราทดสอบกับ proxy ตัวร้ายของจริง

ฟีเจอร์ที่มีเหตุผลในการมีอยู่ทั้งหมดคือการรอดจากเครือข่ายที่มีเจตนาร้าย จะตรวจสอบด้วย unit test อย่างเดียวไม่ได้ — unit test ไม่มี proxy ก่อนเปิดใช้ เรารันแอปตัวจริงผ่าน reverse proxy ในเครื่องที่ตั้งค่าให้ทำสิ่งที่ proxy องค์กรทำเป๊ะๆ: ส่งต่อ HTTPS ปฏิเสธ WebSocket upgrade ด้วย 403

ร่องรอยใน log คือใบเสร็จ: ความพยายามต่อ WebSocket ที่ถูกบล็อกสี่ครั้ง, signature ของการใช้จนหมดที่ถูกจดจำได้, การสลับไป transport แบบ HTTPS โดยอัตโนมัติ แล้วก็เซสชันถอดเสียง 96 วินาทีที่แข็งแรงบน HTTPS ล้วน — 66 segment ถอดเสียง ไม่มีหลุดเลย การ failover ทำงานได้เพราะเราเฝ้าดูมัน fail over

บทเรียนที่เอาไปใช้ต่อได้สามข้อ

  1. "มันใช้ได้บน Wi-Fi ที่กระตุก" กับ "มันใช้ได้หลัง proxy ที่มีเจตนาร้าย" คือคำรับประกันคนละอย่าง อันหนึ่งต้องการการ reconnect อีกอันต้องการ transport คนละแบบ เอามารวมกันเมื่อไหร่ ก็ทิ้งผู้ใช้องค์กรทั้งกลุ่มไว้ให้พังแบบเงียบๆ
  2. การจัด error ของคุณ อาจซ่อนฟีเจอร์ของคุณเองไม่ให้มันเห็นตัวเอง กฎที่ถูก 99% ของเวลา (403 = auth ร้ายแรง) กลับผิดพอดีสำหรับ 1% ที่ฟีเจอร์นี้มีอยู่เพื่อรับใช้ เวลาคุณเพิ่ม fallback ให้ตรวจดูว่าเงื่อนไข trigger มันไปถึง fallback ได้จริงไหม
  3. ทดสอบตัวศัตรู ไม่ใช่แค่เส้นทางที่ราบรื่น การทดสอบ "รอดจาก proxy ที่บล็อก WebSocket" อย่างซื่อสัตย์เพียงอย่างเดียวคือ proxy ที่บล็อก WebSocket เราสร้างมันขึ้นมาเอง

GeekBye v2.0.8 ปล่อย HTTPS fallback แบบมี flag กำกับและผ่านการตรวจสอบแล้ว สำหรับงานด้านความเสถียรที่อยู่ข้างกัน ดูทำไม AI notetaker ของคุณถึงหยุดเมื่อ Wi-Fi ห่วย และสำหรับรีลีสข้างเคียงในซีรีส์นี้ ดูทำไม AI notetaker ของคุณถึงหยุดบันทึกเสียงกลางประชุม (v2.0.9) และทำไม AI ถอดเสียงถึงฟังศัพท์เทคนิคผิด (v2.0.11)

บทความที่เกี่ยวข้อง

วันที่แอปของเรายิง DDoS ใส่ตัวเอง
Steven
Steven2 นาทีที่อ่าน

วันที่แอปของเรายิง DDoS ใส่ตัวเอง

กองงานอัปโหลดที่ค้างอยู่ ถูกปล่อยออกมาทีเดียวทั้งหมดตอนเปิดแอป กลายเป็นการเปลี่ยนทุก client ของ GeekBye ให้เป็นการโจมตีแบบ denial-of-service เล็กๆ ใส่เซิร์ฟเวอร์ของเราเอง วิธีแก้ — และบันได connection-liveness ที่มันบังคับให้เราต้องสร้าง — เป็นหนึ่งในสิ่งที่มีประโยชน์ที่สุดที่ v2 สอนเรา

ความน่าเชื่อถือ
เครือข่าย
วิศวกรรม
ทำไมการบันทึกหน้าจอถึงจับมอนิเตอร์ผิดตัว (และวิธีที่เราแก้)
Steven
Steven2 นาทีที่อ่าน

ทำไมการบันทึกหน้าจอถึงจับมอนิเตอร์ผิดตัว (และวิธีที่เราแก้)

บนเครื่องที่ต่อสองจอ GeekBye บันทึกและแคปหน้าจอหลักเสมอ ไม่ว่าคุณจะทำงานอยู่บนจอไหน การแก้คือฟังก์ชันเล็กๆ ตัวเดียว — แต่เวอร์ชันแรกของมันผิด และ code review จับได้ว่าทำไม

บันทึกหน้าจอ
หลายจอ
วิศวกรรม
ทำไม AI Notetaker ของคุณถึงหยุดบันทึกเสียงกลางประชุม
Steven
Steven2 นาทีที่อ่าน

ทำไม AI Notetaker ของคุณถึงหยุดบันทึกเสียงกลางประชุม

แอปของเราเองปิดการประชุมของเราไปสองครั้ง ทั้งที่อีกฝ่ายกำลังพูดค้างอยู่กลางประโยค เส้นทางการสืบสวนนำไปสู่ idle timer เจตนาดีที่ได้ยินแค่เสียงคุณคนเดียว — และบั๊กตัวที่สองที่อาจล็อกเดสก์ท็อปทั้งเครื่องของคุณ ทั้งคู่แก้แล้วใน GeekBye v2.0.9

ความเสถียร
การประชุม
วิศวกรรม