2 คะแนน โดย GN⁺ 2023-11-26 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • รีโพซิทอรีนี้เป็น การทดลองโค้ดแบบง่าย ที่สร้างขึ้นโดยได้รับแรงบันดาลใจจากงานของ Björn Staal พร้อมลิงก์ข้อมูลเพิ่มเติมเกี่ยวกับไอเดียต้นฉบับ
  • การรันในเครื่องทำโดยติดตั้ง npm i แล้วเปิดเทอร์มินัล 2 หน้าต่าง หนึ่งหน้าต่างสำหรับรัน เซิร์ฟเวอร์ และอีกหน้าต่างสำหรับรัน สแตติกเซิร์ฟเวอร์ของไคลเอนต์
  • เซิร์ฟเวอร์รันด้วย node server/server.js และไคลเอนต์รันด้วย cd client && http-server
  • การดูการทดลองให้เปิดแท็บเบราว์เซอร์ 2 แท็บ โดยเปิด localhost:8080?b=1 และ localhost:8080?b=2 ตามลำดับ
  • แผนในอนาคตรวมถึง โหมด localStorage เท่านั้น, การรองรับหน้าต่างได้ไม่จำกัดจำนวนพร้อมตัด URL query ออก, และการย้ายไปใช้ WebRTC

ภาพรวมโปรเจกต์

  • Momciloo/fun-with-sockets เป็นโปรเจกต์ สำรวจโค้ดแบบง่าย ที่ได้รับแรงบันดาลใจจากงานของ Björn Staal
  • ข้อมูลเพิ่มเติมเกี่ยวกับไอเดียต้นฉบับลิงก์ไปที่ โพสต์บน LinkedIn
  • ใน README มีภาพบันทึกหน้าจอของการทดลองรวมอยู่ด้วย

วิธีรันในเครื่อง

  • ติดตั้ง dependencies ก่อน
    • npm i
  • เปิดเทอร์มินัลเพิ่มอีกหนึ่งหน้าต่าง เพื่อใช้รวม 2 หน้าต่าง
  • ในเทอร์มินัลแรก ให้รัน เซิร์ฟเวอร์
    • node server/server.js
  • ในเทอร์มินัลที่สอง ให้ย้ายไปยังไดเรกทอรี ไคลเอนต์ แล้วรันสแตติกเซิร์ฟเวอร์
    • cd client && http-server
  • ในเบราว์เซอร์ ให้เปิดสองแท็บโดยใช้ค่า query ต่างกัน
    • localhost:8080?b=1
    • localhost:8080?b=2

ไอเดียในอนาคต

  • มีแผนเพิ่มแฟลกสำหรับรันเฉพาะ โหมด localStorage
  • มีแผนเพิ่มตัวเลือกที่รองรับหน้าต่างได้ไม่จำกัดจำนวน และตัดความจำเป็นของ query ใน URL ออก
  • มีแผนย้ายแนวทางการพัฒนาไปเป็น WebRTC

1 ความคิดเห็น

 
GN⁺ 2023-11-26
ความเห็นบน Hacker News
  • เดโมเจ๋งมาก สงสัยว่าจะทำงานอย่างไรกับ หลายจอภาพ
    ชอบที่เจ้าตัวออกมายอมรับเองโดยสมัครใจว่าได้แรงบันดาลใจโดยตรงจากอีกคนและให้เครดิตต้นทาง อยากให้มีคนแบบนี้ในวงการซอฟต์แวร์มากขึ้น

  • วิธีแบบนี้หรือแบบใกล้เคียงกันน่าจะมีประโยชน์กับการ จัดการเลเยอร์ ในโปรแกรมวาดภาพอย่าง Krita, Inkscape, Gimp
    อาจทำเป็นแผงแท็บอย่างง่ายภายในหน้าต่างแอปหลักทั้งหมด และให้เลเยอร์ของแท็บที่เลือกเป็นเลเยอร์ที่กำลังใช้งานสำหรับการแก้ไข

  • จำได้ว่าเมื่อก่อนก็มีเดโมที่ใช้ ตำแหน่งและขนาด ของหน้าต่างอยู่หลายอันเหมือนกัน เคยมีเดโมจำลองฟิสิกส์ด้วย จำไม่ได้ว่าเป็นของเหลวหรือของแข็งหลายชิ้น แต่สามารถปล่อยวัตถุจากหน้าต่างหนึ่งไปอีกหน้าต่างหนึ่งได้
    ดูแล้วน่าจะทำได้ด้วยแค่ช่องทางส่งข้อความระหว่างหน้าต่างโดยไม่ต้องถึงขั้นใช้ socket ด้วยซ้ำ ถ้าหน้าต่างหนึ่งเปิดหน้าต่างลูกขึ้นมา มักจะมีสิทธิ์เข้าถึงพิเศษต่างจากแท็บ/หน้าต่างที่ปกติแยกกันอยู่ เลยดูเหมือนว่าน่าจะทำเวอร์ชันที่ใช้ในเครื่องล้วน ๆ ได้ไม่ยาก

  • ถ้าชอบอะไรแบบนี้ WindowKill ก็น่าจะสนุก เป็นวิดีโอเกมคล้าย Asteroids ที่ใช้ หลายหน้าต่าง ซึ่งซ้อนและโต้ตอบกันได้อย่างชาญฉลาด
    ต้องยิงขอบหน้าต่างด้วย ไม่งั้นหน้าต่างจะหดลง ช่วงท้ายเกมยังมีหน้าต่างเพิ่มขึ้นมาพร้อมศัตรูบอสอยู่ข้างในด้วย
    วิดีโอการเล่น: https://youtu.be/7iP68FZWVxM

  • ลิงก์ทวีตของงานต้นฉบับจาก Bjorn Staal หายไปแล้ว เลยสงสัยว่ามีลิงก์ไหนให้ดูได้ไหมว่ามันคืออะไร

  • นึกถึงเดโมเจ๋ง ๆ ที่เล่น Pong ด้วยหน้าต่างเบราว์เซอร์: http://stewd.io/pong/

  • สงสัยว่าจะมีใครอธิบายได้ไหมว่ามันหมายถึงอะไร ไม่แน่ใจว่าตัวเองเข้าใจ GIF ในหน้า GitHub ถูกไหม เพราะดูเหมือนแค่หน้าต่างแชร์ข้อมูลกัน

    • แก่นสำคัญไม่ใช่แค่หน้าต่างคุยกันได้ แต่คือการเปิดเผย พิกัดหน้าต่าง ผ่าน browser API แล้วนำไปใช้
    • มันดูเหมือนโครงสร้างหลายไคลเอนต์กับเซิร์ฟเวอร์เดียว แต่ละหน้าต่างเป็นไคลเอนต์แยกกัน แล้วส่งข้อมูลเรขาคณิตของหน้าจอไปให้เซิร์ฟเวอร์ จากนั้นเซิร์ฟเวอร์ก็ส่งเลย์เอาต์ที่ต่างกันกลับมาสำหรับแต่ละไคลเอนต์ เพื่อให้คอนเทนต์ดูเหมือนเป็นวัตถุชิ้นเดียวที่พาดผ่านหลายหน้าต่าง
  • เจ๋งดี ดูเป็นธรรมชาติกว่าถ้าสี่เหลี่ยมของ หน้าต่างที่โฟกัสอยู่ ถูกวาดไว้บนสุด

    • เดาว่าทำแบบนั้นเพื่อให้เห็นว่าไม่ได้ใช้แค่ความโปร่งใสธรรมดา
  • แต่ไม่เข้าใจว่าทำไมถึงมีดีเลย์ ระดับนี้มันน่าจะง่ายพอให้ตอบสนองได้ทันทีไม่ใช่เหรอ?

    • เพราะมันรันอยู่ในเบราว์เซอร์ ระหว่างการขยับเมาส์แบบง่าย ๆ กับการเปลี่ยนพิกัดวัตถุแบบง่าย ๆ ยังมี ชั้นระบบและแอปพลิเคชัน อีกหลายชั้นคั่นอยู่ ทั้งการส่งเหตุการณ์ไปยังโค้ดที่ตีความหรือคอมไพล์แล้ว และการส่งการเปลี่ยนสถานะไปยังหน้าจอ
      ต่อให้เป็นเนทีฟ การทำให้สองหน้าต่างที่แยกกันขยับเหมือนกันแบบทันทีทันใดก็ไม่ใช่เรื่องเล็กเสมอไป เช่น เคยมีบทความบอกว่า GUI toolkit บางตัวทำให้การปรับขนาดหน้าต่างแบบลื่นไหลเป็นไปไม่ได้ ต่อให้สร้างทุกอย่างเองก็ยังต้องหวังว่าระบบจะเร็วพอในการแจ้งหน้าต่างและดันบิตแมปขึ้นหน้าจอ ทางที่ดีกว่าคือใช้ compositor ของซอฟต์แวร์/ฮาร์ดแวร์ทั้งระบบ แล้วเพิ่มเลเยอร์แยกตามวัตถุและเปลี่ยนแค่พิกัด แต่ถึงอย่างนั้น compositor ก็ยังต้องดีพอจะรองรับการอัปเดตเกิน 60/120/144 ครั้งต่อวินาทีเมื่อจำเป็น
    • การอ่านตำแหน่งหน้าต่างช้าอย่างน่าเสียดาย เป็นข้อจำกัดของ ฟีเจอร์ในเบราว์เซอร์
    • สงสัยว่าถ้าใช้ postMessage API โดยไม่ผ่านเครือข่ายจะตอบสนองได้ฉับไวขึ้นไหม
    • การที่ หน้าต่างหรือแท็บเบื้องหลังถูกลดลำดับความสำคัญ ก็อาจเป็นอีกปัจจัยหนึ่ง
    • น่าจะเป็นเพราะความหน่วงของเครือข่ายจาก WebSocket และส่วนตัวก็เคยเจอว่าการอัปเดตตำแหน่งหน้าต่างกระตุกแปลก ๆ เป็นบางครั้งเหมือนกัน
  • เป็นตัวอย่างที่ใช้ LocalStorage ได้สนุกดี
    เคยใช้ เทคนิคแชร์ LocalStorage แบบเดียวกันเพื่ออัปเดตหน้าต่างเป้าหมายตอนที่มีการเปลี่ยนค่าตั้งจากหน้าต่างเบราว์เซอร์อีกบาน แค่ฟังอีเวนต์ storage.onChanged เพื่อทำการอัปเดตก็พอ

    • อันนี้ดูเหมือนจะไม่ได้ใช้ local storage นะ น่าจะเป็นโครงสร้าง เซิร์ฟเวอร์ที่อิงกับ WebSocket ซึ่งคอยส่งตำแหน่งของกล่องอื่น ๆ ไปยังไคลเอนต์ทุกครั้งที่มีการขยับ