한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

คู่มือเกมแลค › L8 ซ็อกเก็ตและโปรโตคอล

keepalive ค่าเริ่มต้น 2 ชั่วโมง TCP keepalive defaults

ID สาเหตุ sk-keepalive · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ พัฒนาไคลเอนต์ (ทีมพัฒนาเกม), อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา)

เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →

ถ้าอีกฝั่งหายไปโดยไม่ส่งสัญญาณปิด TCP จะรู้ตัวหลังผ่านไปนานมาก keepalive (ฟีเจอร์ของ TCP ที่ตรวจว่าการเชื่อมต่อที่ idle ยังอยู่หรือไม่) ปิดไว้เป็นค่าเริ่มต้น และต่อให้เปิด ก็ต้อง idle ครบ 2 ชั่วโมงก่อนจึงเริ่มตรวจ

ทำไม ไคลเอนต์หายไปโดยไม่ส่งสัญญาณปิด เพราะเครื่องดับหรือเน็ตขาด → ผลคือ เซิร์ฟเวอร์ถือว่าการเชื่อมต่อยังอยู่ (keepalive ค่าเริ่มต้น 7,200 วินาที ถ้ามีข้อมูลที่กำลังส่งอยู่ จะใช้ประมาณ 15 นาทีกว่าจะเลิกส่งซ้ำ) → บนหน้าจอ เหลือตัวผีของตัวละครอยู่ในเกม และพอเชื่อมต่อใหม่ก็เจอข้อผิดพลาด “ล็อกอินอยู่แล้ว”

อาการ
เข้าเกมไม่ได้/โหลดไม่จบ, มองไม่เห็น/ตัวผี
ปัจจัย
แพ็กเก็ตหาย
ใครเจอ
เราคนเดียว
เกิดเมื่อไร
หลังอยู่เฉย ๆ สักพัก, หลังล็อกอิน/หลังปิดปรับปรุง
ผู้รับผิดชอบ
ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ พัฒนาไคลเอนต์ (ทีมพัฒนาเกม), อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา)
งานฝั่งทีมพัฒนาเกม
เซิร์ฟเวอร์: ตอบ heartbeat และถ้าไม่ได้รับนานเกินกำหนดให้ปิดการเชื่อมต่อเองก่อน (ปรับ TCP_KEEPIDLE และ TCP_USER_TIMEOUT), เมื่อเชื่อมต่อใหม่ให้ใช้ session token แทนที่เซสชันเดิมแล้วเล่นต่อ ไคลเอนต์: ส่ง heartbeat ระดับเกมทุกไม่กี่วินาทีถึงหลายสิบวินาที (ไม่เกินครึ่งหนึ่งของ idle timeout ที่สั้นที่สุด), เชื่อมต่อใหม่อัตโนมัติเมื่อหลุด
งานฝั่งทีมอินฟรา
ลดค่าเริ่มต้นของเคอร์เนล (tcp_keepalive_time เป็นต้น) สำหรับซ็อกเก็ตที่โค้ดไม่ได้กำหนดค่าเอง (มีผลเฉพาะซ็อกเก็ตที่เปิด SO_KEEPALIVE)
ตัวเลขที่ควรรู้
ค่าเริ่มต้นของ Linux จะเริ่มตรวจเมื่อ idle ครบ 7,200 วินาที แล้วส่ง probe 9 ครั้งห่างกันครั้งละ 75 วินาที ถ้าไม่มีการตอบกลับเลยจะตัดการเชื่อมต่อ รวมแล้วประมาณ 2 ชั่วโมง 11 นาที ค่าเริ่มต้นของ Windows ก็ต้อง idle 2 ชั่วโมงก่อนจึงเริ่มตรวจเช่นกัน
บนกราฟ
สูงเฉพาะบางกลุ่ม · เวลาที่ผ่านไปนับจากรับข้อมูลครั้งล่าสุดของแต่ละการเชื่อมต่อ
จุดที่ต้องดู
lastrcv (ms ที่ผ่านไปนับจากรับข้อมูลครั้งล่าสุด) และตัวจับเวลา keepalive (timer:(keepalive,…)) ของแต่ละการเชื่อมต่อจาก ss -tnoi เทียบกับบันทึกการปฏิเสธ “ล็อกอินอยู่แล้ว” ของเซิร์ฟเวอร์เกม
สัญญาณว่าใช่
ยังมีการเชื่อมต่อ ESTABLISHED ที่ lastrcv นานหลายนาทีถึงหลายชั่วโมง และการเชื่อมต่อใหม่ของบัญชีนั้นถูกปฏิเสธด้วย “ล็อกอินอยู่แล้ว”
สัญญาณว่าไม่ใช่
ไม่มีการเชื่อมต่อที่เงียบไปนาน แต่ยังขึ้น “ล็อกอินอยู่แล้ว”: น่าจะเป็นโค้ดเก็บกวาดเซสชันของเซิร์ฟเวอร์เกม
วิธีตรวจ
ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)

แหล่งอ้างอิง

  1. tcp(7) — Linux manual page Linux man-pages
    หลัง idle 7,200 วินาที ส่ง probe 9 ครั้งห่างกัน 75 วินาที (เพิ่มอีกประมาณ 11 นาที), มีผลเฉพาะซ็อกเก็ตที่เปิด SO_KEEPALIVE, TCP_KEEPIDLE และ TCP_USER_TIMEOUT
  2. RFC 9293: Transmission Control Protocol (TCP) IETF
    keepalive ต้องปิดเป็นค่าเริ่มต้น และช่วง idle เริ่มต้นต้องไม่ต่ำกว่า 2 ชั่วโมง
  3. SO_KEEPALIVE socket option Microsoft
    ไทม์เอาต์เริ่มต้นของ TCP keepalive บน Windows คือ 2 ชั่วโมง
  4. ss(8) — Linux manual page iproute2
    lastrcv (ms ที่ผ่านไปนับจากรับข้อมูลครั้งล่าสุด) ใน -i, timer:(keepalive,…) ใน -o

สาเหตุที่ควรดูประกอบ

ชั้นเดียวกัน: L8 ซ็อกเก็ตและโปรโตคอล

สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (เข้าเกมไม่ได้/โหลดไม่จบ)

ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง