วิธีการทำงาน

ไม่มี server กลางเลย

แอปนี้ไม่มี backend, ไม่มีฐานข้อมูล, ไม่มี server เก็บภาพวาดของคุณที่ไหนทั้งนั้น การเชื่อมต่อเป็นแบบ WebRTC DataChannel ตรงระหว่างเบราว์เซอร์สองเครื่อง — เมื่อวาด pixel ข้อมูลจะวิ่งจากเครื่องคุณ ไปเครื่องเพื่อนโดยตรง ไม่ผ่านเซิร์ฟเวอร์ของใครทั้งสิ้น (ไม่ใช่ของเรา ไม่ใช่ของใครอื่น)

แล้วสองเครื่องรู้จักกันได้ยังไงถ้าไม่มี server?

การต่อ WebRTC ต้องมีขั้นตอน "signaling" แลกข้อมูลเทคนิค (SDP) กันก่อนครั้งเดียว ปกติแอปอื่นจะใช้ server กลางส่งข้อมูลนี้ให้อัตโนมัติ แต่แอปนี้ตัด server กลางออกทั้งหมด แล้วให้ คุณเป็นคนส่งข้อมูลนั้นเอง ผ่านช่องทางไหนก็ได้ที่คุณสะดวก (LINE, ข้อความ, อะไรก็ได้):

หลังจากขั้นตอนนี้เสร็จ ทั้งสองเครื่องคุยกันตรงตลอดเซสชัน ไม่ต้องแลกโค้ดซ้ำอีก

ข้อจำกัดของ NAT (ต่อไม่ติดบ้างเป็นเรื่องปกติ)

แอปนี้ใช้ STUN server สาธารณะของ Google (stun.l.google.com) ช่วยให้สองเครื่องรู้ที่อยู่ สาธารณะของกันและกัน แต่ ไม่มี TURN server (ตัวรีเลย์สำรองเวลาต่อตรงไม่ได้) เพราะการมี TURN หมายถึงต้องมี server กลางรับส่งข้อมูลจริง ๆ ซึ่งขัดกับหลักการ "ไม่มี server" ของโปรเจกต์นี้ ผลคือ: เครือข่ายบางคู่ (โดยเฉพาะ NAT แบบ symmetric ที่พบใน Wi-Fi องค์กร/มหาวิทยาลัยบางที่ หรือเน็ตมือถือบางค่าย) อาจต่อกันตรงไม่ได้เลย ถ้าเจอแบบนี้ ลองสลับไปใช้เน็ตอื่น (เช่นจาก Wi-Fi เป็นเน็ตมือถือ) มักช่วยได้ — งานวาดที่มีอยู่จะไม่หายไป และเล่นคนเดียวยังใช้ได้ตามปกติเสมอ

ความเป็นส่วนตัว

เพราะภาพวิ่งตรงระหว่างสองเครื่องเท่านั้น จึงไม่มีใครนอกจากสองคนที่เชื่อมต่อกันเห็นภาพวาดนี้ได้ — ไม่มีการ อัปโหลดขึ้น server ไหน ไม่มีการเก็บ log ฝั่งเรา สิ่งที่เก็บมีแค่ใน localStorage ของเบราว์เซอร์ คุณเอง (สำหรับกันงานหายตอนรีเฟรช) เท่านั้น

ทำไม TDD แค่บางไฟล์

lib/grid.ts (LWW conflict resolution), lib/proto.ts (encode/decode ข้อความ) และ lib/codes.ts (บีบอัด SDP เป็นโค้ด + validate) คือตรรกะที่ผิดพลาดแล้วทำข้อมูลเพี้ยนหรือ เชื่อมต่อไม่ได้เลย เลยเทสต์แน่นด้วย TDD ส่วนการเชื่อมต่อ WebRTC จริง (lib/rtc.ts) และ UI (zoom/pan/canvas) เป็น "ของจริง" ที่ต้องอาศัย browser API (RTCPeerConnection) ซึ่งไม่มีใน environment ทดสอบ (jsdom) — เส้นทางโค้ดของโค้ดเชื่อมต่อ (encode/decode/validate) จึงถูกยืนยัน ผ่าน unit test ของ lib/codes.ts แทน ส่วนการต่อจริงต้องทดสอบมือ 2 เบราว์เซอร์ (ดู README)