Auto-Heartbeat: กันแชร์ที่นั่ง License แบบอัตโนมัติ

อ่าน 7 นาที

ใช้ startAutoHeartbeat ใน SDK (JS/Python/C#) ให้แอปส่งสัญญาณ "ยังออนไลน์" เป็นรอบ ๆ เซิร์ฟเวอร์ยึดที่นั่งคืนอัตโนมัติเมื่อเงียบเกิน 3 เท่าของ interval — กันการแชร์ที่นั่งโดยไม่ต้องล็อกเครื่องตายตัว

สำหรับ floating license ปัญหาคือ ถ้าแอปปิดดื้อ ๆ (เครื่องดับ, แอป crash) ที่นั่งจะค้างไม่มีใครคืน คนอื่นเลยใช้ไม่ได้ ทางแก้คือ heartbeat — ให้แอปส่ง สัญญาณ “ยังออนไลน์” เป็นรอบ ๆ ถ้าเงียบเกินกำหนด เซิร์ฟเวอร์ยึดที่นั่งคืนเอง SDK มี startAutoHeartbeat ทำส่วนนี้ให้อัตโนมัติทั้ง 3 ภาษา

มันทำงานอย่างไร

startAutoHeartbeat จะส่ง beat แรกทันที แล้ววนส่งซ้ำตาม intervalSeconds แต่ละ beat อัปเดต last_heartbeat_at ของที่นั่งนั้น ฝั่งเซิร์ฟเวอร์มี cron ที่ ยึดที่นั่งคืนเมื่อเครื่องเงียบเกิน ประมาณ 3 เท่า ของ heartbeatIntervalSeconds ใน policy (เฉพาะ policy ที่ heartbeatRequired) — เผื่อ beat หล่นไป 1–2 ครั้งจากเน็ตสะดุดโดยไม่เด้ง ผู้ใช้ออก

ใช้งานใน JS / Python / C#

ทุก SDK ออกแบบให้ทนทาน: error ชั่วคราว (เน็ตหลุด, RATE_LIMITED) จะส่งเข้า onError แล้ว loop ทำงานต่อ ส่วนสถานะสุดท้าย (LICENSE_REVOKED, LICENSE_SUSPENDED, LICENSE_EXPIRED, MACHINE_NOT_FOUND) จะ หยุด loop เอง ไม่ยิงต่อให้เปลือง

JavaScript (keythai-sdk)
import { KeyThaiClient } from "keythai-sdk";

const client = new KeyThaiClient({ apiKey: "kt_live_xxxxxxxxxxxx" });
const key = "KEYT-AB12-3C4D-5E6F-7G8H-9J0K";

// 1) activate ครั้งแรกเพื่อยึดที่นั่ง
await client.activate(key, { fingerprint, platform: "windows" });

// 2) ส่ง heartbeat อัตโนมัติ — beat แรกทันที จากนั้นทุก ๆ interval
const stopper = client.startAutoHeartbeat(key, fingerprint, {
  intervalSeconds: 60, // ตั้งให้ <= heartbeat_interval_seconds ของ policy
  onBeat: (res) => console.log("ยังออนไลน์:", res.status),
  onError: (err) => console.warn("heartbeat ล้มเหลว (ชั่วคราว):", err),
});

// ตอนปิดแอป — คืน loop (idempotent)
stopper.stop();
Python (keythai)
from keythai import KeyThaiClient, get_device_fingerprint

client = KeyThaiClient("kt_live_xxxxxxxxxxxx")
fp = get_device_fingerprint()
client.activate(key, fp)  # ต้อง activate ให้มีที่นั่งก่อน

handle = client.start_auto_heartbeat(
    key, fp,
    interval_seconds=60,   # None = ใช้ค่า policy heartbeat_interval_seconds ไม่งั้น 300s
    on_beat=lambda res: print("beat ok"),
    on_error=lambda exc: print("heartbeat ล้มเหลว:", exc),
)
# ... แอปทำงาน ...
handle.stop()   # เรียกซ้ำได้ ไม่มีปัญหา
C# (KeyThai.Client)
using KeyThai;

var client = new KeyThaiClient("kt_live_xxxxxxxxxxxx");
var fp = KeyThaiClient.GetDeviceFingerprint();

// คืนค่า IDisposable — เรียก Dispose() เพื่อหยุด
IDisposable beat = client.StartAutoHeartbeat(
    "KEYT-AB12-3C4D-5E6F-7G8H-9J0K", fp,
    interval: TimeSpan.FromSeconds(60),   // null = policy หรือ 300s
    onBeat: r  => Console.WriteLine($"beat #{r.BeatNumber}"),
    onError: ex => Console.WriteLine($"heartbeat error: {ex.Message}"));

// ตอนปิดแอป (เช่นใน OnFormClosed):
beat.Dispose();

ตั้ง interval ให้ถูก

ค่าเริ่มต้นของ SDK คือ 300 วินาที เพราะ response ไม่ได้ส่งค่า heartbeat_interval_seconds ของ policy กลับมา SDK จึงเดาเองไม่ได้ ให้ดึงค่าจริง จาก listPolicies() (ฟิลด์ heartbeat_interval_seconds) แล้วส่งผ่าน intervalSeconds หลักการง่าย ๆ: beat ที่หรือถี่กว่าค่า policy เพราะเซิร์ฟเวอร์ยึดคืนที่ราว 3 เท่า ถ้า beat ห่างเกินไปที่นั่งจะถูกยึดทั้งที่ยังใช้อยู่

เกร็ด: บน Node ตัวจับเวลาถูก unref() จึงไม่กันไม่ให้ process ปิด, ใน C# ผูกกับ cancellationToken ได้, และเรียก startAutoHeartbeat ซ้ำด้วย key + fingerprint เดิมจะแทนที่ loop เก่า อย่าลืม activate ให้มีที่นั่งก่อนเริ่ม beat

heartbeat คือหัวใจของ floating license — ถ้ายังไม่แน่ใจว่า floating เหมาะกับคุณไหม อ่าน Floating License คืออะไร หรือดูภาพรวมการกัน crack หลายชั้นที่ ป้องกันโปรแกรมโดน Crack

พร้อมปกป้องซอฟต์แวร์ของคุณแล้วหรือยัง?

เริ่มต้นฟรี ไม่ต้องใช้บัตรเครดิต ออก license key แรกของคุณได้ในไม่กี่นาที