Kotchasan PHP Framework

ตัวอย่างการใช้งาน AJAX กับเว็บไซต์ ตอนที่ 5

ตัวอย่างนี้จะเป็นตัวอย่างการ Synchronize เวลาด้วย Ajax ซึ่งเป็นประโยชน์ที่สำคัญอีกอย่างของ Ajax

โดยปกติแล้วหากมีการเขียนสคริปต์ที่ต้องมีความเกี่ยวข้องกับเวลา หากใช้เวลาที่มาจาก Javascript ตรงๆ จะเป็นการไม่ปลอดภัยอย่างยิ่ง เนื่องจากเวลาที่ได้มาจาก Javascript สามารถแก้ไขได้ง่ายๆบนบราวเซอร์ เช่นในกรณีที่มีการจับเวลาในการทำข้อสอบ ถ้าผู้ใช้สามารถแก้ไขเวลาได้ก็จะทำให้ผู้ใช้สามารถมีเวลาได้ไม่จำกัดในการทำข้อสอบ ในทางปฏิบัติจึงต้องมีการใช้เวลาที่มาจาก Server โดยเมื่อมีการเริ่มต้นทำข้อสอบให้บันทึกเวลาเก็บไว้ และบันทึกอีกครั้งตอนส่งข้อสอบ เมื่อนำเวลาทั้งสองมาลบกันก็จะได้เวลาที่ใช้ในการทดสอบ

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

วิธีข้างต้นใช้งานได้ในทางปฎิบัติก็จริง แต่ก็ยังมีปัญหาอีกหลายอย่าง เช่น หากมีการขัดจังหวะโดยผู้ใช้ เครื่องค้าง หรือเกิดเหตุไม่คาดฝันใดๆขึ้นหรือเกิดการรีเฟรช หรือแม้กระทั่งการเปลี่ยนหน้า จะทำให้เราสูญเสียเวลาในทันที ปัญหานี้สามารถแก้ไขได้ด้วยการตรวจสอบเวลาระหว่าง Server และบราวเซอร์ให้ตรงกันอย่างสม่ำเสมอด้วย Ajax

แนวคิดก็ตรงไปตรงมาเลยครับ โดยการใช้ Ajax ส่งข้อมูลกลับไปสอบถามเวลาปัจจุบันจาก Server เป็นระยะๆ เมื่อได้ข้อมูลเวลากลับมาแล้วก็ใช้ข้อมูลนั้นในการปรับเวลาของบราวเซอร์ให้ตรงกับบน Server อีกที

ตัวอย่างนี้เป็นการแสดงเวลาที่ส่งมาจาก Server โดยการใช้ Ajax อ่านเวลามาจาก Server ทุก 1 นาทีเมื่อได้ข้อมูลมาแล้วก็นำเวลาที่ได้ไปแสดงผลทันที เสร็จแล้วให้ Javascript อีกตัววนลูปปรับปรุงเวลาที่แสดงผลทุก 1 วินาที

ส่วนแรกเป็น HTML สำหรับแสดงเวลาเฉยๆไม่มีอะไรซับซ้อนนะครับ สามารถลองแก้ไขเวลาดูได้
<input type="text" id="demo_txt" value="00:00:00">

Javascript ผมแยกอธิบายออกเป็นสองส่วนนะครับ ส่วนแรกคือการจับเวลาด้วย Javascript
// เริ่มต้นจับเวลาด้วย Javascript
new Clock('demo_txt');

Clock(id, options)
  • id (string) ชื่อไอดีของ element ที่แสดงเวลา
  • options (Object) ค่าพารามิเตอร์ที่ส่งให้กับ Clock มีแค่ 2 ตัว
    • reverse (boolean) ค่าเริ่มต้นคือ false หมายถึงเป็นนการนับเดินหน้าตามปกติ เช่นการแสดงเวลา หรือ true จะทำให้ Clock นับเวลาถอยหลัง เช่นการใช้เป็นนาฬิกาจับเวลา
    • onTimer (function) เป็นฟังก์ชั่นเหตุการณ์เมื่อมีการจับเวลา ซึ่งจะเกิดขึ้นทุกวินาทีตามที่ Clock ทำงาน มีพารามิเตอร์อีก 3 ตัว คืนค่าเวลาปัจจุบันคือ function(Hour, Minute, Second) {...}
Javascript ส่วนที่สอง เป็นฟังก์ชั่น Ajax อัปเดทเวลาจาก Server
// ฟังก์ชั่น Ajax อ่านข้อมูลจาก Server เป็นระยะ
new GAjax().initLoading('demo_txt').autoupdate('index.php/index/model/index/time', 60, null, function (xhr) {
    $E('demo_txt').value = xhr.responseText;
});

autoupdate เป็นเมธอดหนึ่งของ GAjax มีพารามิเตอร์ 4 ตัวคือ
  • url (string) เป็น URL ที่ Ajax ใช้ร้องขอข้อมูล โดยทั่วๆไปสำหรับคชสารจะเป็น Model เช่น http://domain.tld/...ndex/model/ajax/post หมายถึงเรียกไปยัง Index\Ajax\Model->post() เป็นต้น
  • interval (int) ช่วงเวลาที่ใช้ในการอัปเดท หน่วยเป็นวินาที
  • getRequest (function) ฟังก์ชั่นสำหรับอ่านค่าพารามิเตอร์ที่ต้องการส่งไปด้วย Ajax รูปแบบ Query String ถ้าไม่มีพารามิเตอร์ส่งไปให้ระบุ null
  • callback (function) เป็นฟังก์ชั่นสำหรับรับค่าที่ส่งกลับมาจาก Ajax โดยจะมีพารามิเตอร์ส่งกลับมาด้วยเป็น XHR Object ตัวอย่าง function(xhr) {...}
จากโค้ดเป็นการใช้ Ajax วนลูปอ่านค่าเวลาจาก Server ทุก 1 นาที (60 วินาที) เมื่อได้ค่ามาแล้วก็เอาไปอัปเดทพื้นที่แสดงผลทันที

สุดท้าย Index\Index\Model->time() ซึ่งเป็นคลาสสำหรับรับค่าที่ส่งมาจาก Ajax ซึ่งตัวอย่างนี้ไม่ได้ทำอะไรเลย แค่ส่งเวลาจาก Server กลับไปแสดงผลเท่านั้น
/**
* อ่านเวลาจาก Server
*
* @param Request $request
*/

public function time(Request $request)
{
    // คืนค่าเวลาปัจจุบันจาก Server
    echo date('H:i:s');
}

สำหรับคนที่สงสัยว่าทำไมต้องทำแบบนี้ ทำไมไม่อ่านเวลาจาก Server มาใช้งานทีเดียวเลย คำตอบก็คือ การส่งรีเควสไปยัง Server ทุก 1 วินาทีไม่ใช่เป็นสิ่งที่น่าทำนัก โดยเฉพาะหากเป็นการทำข้อสอบ ซึ่งอาจจะมีคนจำนวนมากทำข้อสอบพร้อมๆกันซึ่งการส่งรีเควสพร้อมๆกันไปยัง Server อาจทำให้ Server ล่มได้ เราจึงใช้วิธีการส่งเป็นช่วงๆแทน ซึ่งระยะห่างระหว่างแตละช่วงยิ่งแคบเท่าไร เวลาที่ได้ก็จะแม่นยำมากขึ้น

ตัวอย่างนี้ดูได้ที่นี่นะครับ https://projects.kotchasan.com/...ndex.php?module=time