ก่อนอื่นเรามาหา facepage แนวรูปภาพที่เราชื่นชอบกันก่อนเลย และในที่นี้ขอเป็นเพจ
9GAG in Thai https://www.facebook.com/9gaginthai
จากนั้นนำชื่อของเพจที่อยู่บน Url นั่นก็คือ 9gaginthai มาใส่ใน api นี้
https://graph.facebook.com/9gaginthai/albums?fields=id%2Cname
ซึ้งจากที่เห็นในส่วนของ query ของ url ก็จะเห็นได้ว่า ผมต้องการ fields เพียงแค่ id และ ชื่อของอัลบั้มเท่านั้น ซึ้งถ้าไม่ระบุอะไร facebook ก็จะให้เรามาทั้งหมด ไม่ว่าจะเป็นการ like comment เป็นต้น ก้ไปศึกษารูปแบบข้อมูลเอานะครับ
จะเห็นผลลัพธ์ json ในรูปแบบดังนี้ จากนั้น เราจะนำ id ของ อัลบั้มรูปที่เนราต้องการมาใส่ไว้ใน api นี้ ดังนี้
โดยผมเลือก id ของ Timeline Photo มาใช้นั้นคือ 194110460693515
https://graph.facebook.com/194110460693515/photos?limit=30
โดยค่า limit สามารถเลือกได้ และจะกรองเอาเฉพาะฟิวที่เราต้องการก็ได้ แต่ผมจะเลือกมาทั้งหมดเลย
จากผลลัพธ์ ภายใต้ data [] จะมี array ของ object ของรูปอยู่ จามจำนวน limit ที่ได้ทำการร้องขอไป
- id คือ id ของโพส
- create_time โพส ณ เวลาใด
- from โพสโดยใคร
- image[] ภายในจะมีรูปสำหรับทำทัมเนลพร้อมทั้งมีขนาด width และ height ขนาดต่างๆให้เลือกอีกด้วย
- link คือ url ต้นฉบับของโพสนั้นๆ
- source คือ ต้นฉบับของรูป (ซึ้งตรงนี้ละที่ต้องการ อิอิ)
- comment และ like ตรงนี้ไปศึกษาเอานะครับ มีข้อมูลที่เป็นประโยชน์หลายอย่างมากๆ
- width และ height ของรูปต้นฉบับก็มีมาให้น๊ะจ๊ะ
เท่านี้ เราจะเอาข้อมูลไปทำอะไรต่อนั้นก็สุดแท้ แล้วแต่ พวกนายเลยว่าจะทำอะไรเด้อออออ
วันอังคารที่ 19 พฤษภาคม พ.ศ. 2558
รีวิว App MacID ใช้เพื่อปลดล็อกเครื่อง Mac
เนื่องจากปัจจุบัน คอมพิวเตอร์ผมตั้งเอาไว้กับที่เป็นเวลานานๆ และเป็นที่ส่วนรวม และผมก็ไม่ได้อยู่หน้า Mac ของตัวองตลอดเวลา ซึ้งบางครั้งผมก็ลืมที่จะ logout สื่อสังคมออนไลน์ต่างๆของตนเอง
...ดังนั้นจึงจะมีไอ้คุณเพื่อนบางคน แอบดูหรือแอบไปรู้รหัส login เครื่อง Mac ของเรา เพราะการตั้งรหัสเครื่องนั้น คนส่วนใหญ่จะตั้งรหัสสั้นๆ เพื่อที่จะ login เข้าเครื่อง Mac ได้อย่างรวดเร็ว จึงเป็นเหตุให้ไอ้เพื่อนพวกนี้รู้รหัสเครื่องของเราได้ไม่ว่าจะแอพดูหรือเดา หรือบลาๆๆ ด้วยวิธีต่างๆ และจากนั้นมันเอาเอา User facebook หรืออย่างอื่นไปแกล้งเรา ด้วยการโพสข้อความในลักษณะที่ เราเบี่ยงเบนทางเพศ หรือการตั้งสถานะต่างๆที่ทำให้เราเกิดอาการอับอาย หรือผู้อื่นได้รับการเข้าใจผิดเกี่ยวกับเรา ... และสิ่งนี้คือเรื่อง 'ตลก' เฮฮาสำหรับทุกคน
... วันนี้ผมจึงจะมานำเสนอแอพที่จะช่วยปล็ดล๊อกเครื่อง Mac ให้เราได้อย่างรวดเร็ว และทำให้เราตั้งรหัสยาวๆได้ และจะไม่ต้องพิมพ์รหัสให้เพื่อนแอบดูด้วย
App Mac ID
- เครื่อง Mac ที่เข้าใช้ได้
Macbook Air ปี 2011 หรือมากกว่า
Macbook Pro ปี 2012 หรือมากกว่า
iMac ปี 2012 หรือมากกว่า
Mac Mini ปี 2011 หรือมากกว่า
MacPro ปี 2013 หรือมากกว่า
- iPhone ที่เข้าใช้ได้
iPhone4s
iPhone5
iPhone5c
iPhone5s
iPhone6
iPhone6Plus
iPad mini
iPad mini 2
iPad mini 3
iPad 4 gen
iPad Air
iPad Air 2
iPod touch 5 gen
ก่อนอื่นไปโหลดโปรแกรมของ Mac ใน website นี้ก่อนเลย http://macid.co/
ต่อมาไปโหลด App จากทาง iOS ด้วย
ต่อมาก็ไปเปิด บลูทูธ สำหรับทั้ง Mac และก็ iOS จากนั้นก็ไปคลิกเลือกอุปกรณ์บน Mac และกรอกรหัสผ่านบน Mac ให้ตรงกันทั้งสองช่อง เท่านี้ก็พร้อมใช้งานแล้ว
...ดังนั้นจึงจะมีไอ้คุณเพื่อนบางคน แอบดูหรือแอบไปรู้รหัส login เครื่อง Mac ของเรา เพราะการตั้งรหัสเครื่องนั้น คนส่วนใหญ่จะตั้งรหัสสั้นๆ เพื่อที่จะ login เข้าเครื่อง Mac ได้อย่างรวดเร็ว จึงเป็นเหตุให้ไอ้เพื่อนพวกนี้รู้รหัสเครื่องของเราได้ไม่ว่าจะแอพดูหรือเดา หรือบลาๆๆ ด้วยวิธีต่างๆ และจากนั้นมันเอาเอา User facebook หรืออย่างอื่นไปแกล้งเรา ด้วยการโพสข้อความในลักษณะที่ เราเบี่ยงเบนทางเพศ หรือการตั้งสถานะต่างๆที่ทำให้เราเกิดอาการอับอาย หรือผู้อื่นได้รับการเข้าใจผิดเกี่ยวกับเรา ... และสิ่งนี้คือเรื่อง 'ตลก' เฮฮาสำหรับทุกคน
... วันนี้ผมจึงจะมานำเสนอแอพที่จะช่วยปล็ดล๊อกเครื่อง Mac ให้เราได้อย่างรวดเร็ว และทำให้เราตั้งรหัสยาวๆได้ และจะไม่ต้องพิมพ์รหัสให้เพื่อนแอบดูด้วย
App Mac ID
- เครื่อง Mac ที่เข้าใช้ได้
Macbook Air ปี 2011 หรือมากกว่า
Macbook Pro ปี 2012 หรือมากกว่า
iMac ปี 2012 หรือมากกว่า
Mac Mini ปี 2011 หรือมากกว่า
MacPro ปี 2013 หรือมากกว่า
- iPhone ที่เข้าใช้ได้
iPhone4s
iPhone5
iPhone5c
iPhone5s
iPhone6
iPhone6Plus
iPad mini
iPad mini 2
iPad mini 3
iPad 4 gen
iPad Air
iPad Air 2
iPod touch 5 gen
ก่อนอื่นไปโหลดโปรแกรมของ Mac ใน website นี้ก่อนเลย http://macid.co/
ต่อมาไปโหลด App จากทาง iOS ด้วย
ต่อมาก็ไปเปิด บลูทูธ สำหรับทั้ง Mac และก็ iOS จากนั้นก็ไปคลิกเลือกอุปกรณ์บน Mac และกรอกรหัสผ่านบน Mac ให้ตรงกันทั้งสองช่อง เท่านี้ก็พร้อมใช้งานแล้ว
หน้าตา App จากการใช้งานจริง
WebSockets กับเว็บแชทขั้นพื้นฐาน ตอนที่ 3
WebSockets กับเว็บแชทขั้นพื้นฐาน ตอนที่ 3
จากเดิมที่เรามารู้จักกับ concept ทั้งหมด รวมถึงการทำงานในทาง Server ไปแล้วนั้น เราจะมาดูวิธีการทำงานของทาง Client กันบ้าง
*** code ของ client ทั้งหมดอยู่ ณ บทความตอนที่ 2
ส่วนที่ 1
<div id='body'>
<textarea id='log' name='log' readonly='readonly'></textarea><br/>
<input type='text' id='message' name='message' />
</div>
คือส่วนของการแสดงผลหลัก
ส่วนที่ 2
$(document).ready(function() {
log('Connecting...');
Server = new FancyWebSocket('ws://127.0.0.1:9300');
$('#message').keypress(function(e) {
if ( e.keyCode == 13 && this.value ) {
log( 'You: ' + this.value );
send( this.value );
$(this).val('');
}
});
//Let the user know we're connected
Server.bind('open', function() {
log( "Connected." );
});
//OH NOES! Disconnection occurred.
Server.bind('close', function( data ) {
log( "Disconnected." );
});
//Log any messages sent from server
Server.bind('message', function( payload ) {
log( payload );
});
Server.connect();
});
Server = new FancyWebSocket('ws://127.0.0.1:9300');
// คือการสร้างตัวแปร Server เพื่อรองรับการ connect Web Socket ไปยัง ip 127.0.0.1 ที่ port 9300 ที่ได้ setting เอาไว้ที่ Code ทาง Server
// การ bind open เข้าไป เมื่อมีการสั่ง connect ก็จะทำงานตัวนี้
Server.bind('open', function() {
log( "Connected." );
});
// การ bind close เข้าไป พูดง่ายๆคือ เมื่อปิดหน้านี้ไป จะทำการ Disconnect
Server.bind('close', function( data ) {
log( "Disconnected." );
});
// การ bind message เข้าไป คือเมื่อมี Message จากผู้ใช้อื่นๆเข้ามา ก็จะผ่านตัวนี้
Server.bind('message', function( payload ) {
log( payload );
});
// เชื่อมต่อ Web Socket
Server.connect();
// ฟังก์ชันสำหรับการส่งข้อความไปยัง web socket
// โดย send ค่าใน text ไปยัง Server
function send( text ) {
Server.send( 'message', text );
}
// คือ ฟังก์ชันสำหรับการเพิ่มผลลัพธ์ เพื่อแสดงผลในส่วนแสดงผลหลัก
function log( text ) {
$log = $('#log');
//Add text to log
$log.append(($log.val()?"\n":'')+text);
//Autoscroll
$log[0].scrollTop = $log[0].scrollHeight - $log[0].clientHeight;
}
วันพุธที่ 18 มีนาคม พ.ศ. 2558
WebSockets กับเว็บแชทขั้นพื้นฐาน ตอนที่ 2
Web Sockets กับการ Impliment เว็บแชทขั้นพื้นฐาน
ตอนที่ 1 : http://aobkung.blogspot.com/2015/03/websockets-1.htmlตอนที่ 3 : http://aobkung.blogspot.com/2015/05/websockets-3.html
ก่อนอื่นเราจะต้องบอกก่อนว่า จะทำการ implement ในฟั่ง Process ของ server โดยการใช้ Class ของคนที่เขียน WebSocket มาอยู่แล้ว ซึ้งเป็นภาษา PHP และทำออกมาได้ดีพอสมควร (ในแง่การใช้ มันง่ายดี)
สามารถเข้าไป Download ได้ที่
https://github.com/ghedipunk/PHP-Websockets
โดยที่เราจะสนใจ file ที่ชื่อ websockets.php และ users.php
และที่สำคัญจะต้องติดตั้ง PHP Command line มาด้วย ซึ้งผมใช้ Mac OS X ดังนั้นจึงทำการติดตั้งผ่านโปรแกรมที่ชื่อว่า MAMP ซึ้งจะมีเวอร์ชั่นฟรีให้โหลด (ค้นหาเอาเลยใน Google) เอาไปใช้ได้
ขอบเขตของ web chat ที่เราจะเขียน
- เป็นห้อง Chat รวม เมื่อเข้าไปแล้วทุกคนสามารถคุยกันได้ (ทุกคนเห็นข้อความที่เราพิมพ์ออกไป)
- เป็นเมื่อมีคน connect เข้ามา หรือปิดการเชื่อมต่อ (ปิดโปรแกรม) ก็จะแจ้งเตือนให้กับผู้อื่นได้รับทราบด้วย
- บอกหมายเลข ID ของแต่ละคนเพื่อแยกตัวตนซึ้ง Class WebSocketServer จะทำหน้าที่สร้างขึ้นมา
ขั้นตอนที่ 1
เริ่มจากการ Impliment ทางฟั่ง Server กันก่อนเลย (บางแหล่งเริ่มอธิบายจาก Client ก่อน แต่ผมเข้าใจมันมาจากทาง Server ก่อน ดังนั้นขอแบบนี้ละกันนะครับ ฮาๆ)เอาละ เริ่มจากเข้าไปดู code ที่ไฟล์ websockets.php กันก่อน ใน class จะเห็น code ดังนี้
// Called immediately when the data is recieved.จะมี abstract function อยู่ 3 function ให้เราเอาไป implement เอาเอง ซึ้งก็คือ 3 function หลักที่เป็นหัวใจของการทำ Web Socket ก็คือ connected closed และ Process(การ get และ send ข้อมูล) ดังนั้นเราจะสร้าง Class ของเราขึ้นมาเอาไว้ใช้งาน โดนสือทอด Class WebSocketServer ที่คุณ ghedipunk ได้เขียนและนำเอามาลงเอาไว้ใน Github นั้นเอง
abstract protected function process($user,$message);
// Called after the handshake response is sent to the client.
abstract protected function connected($user);
// Called after the connection is closed.
abstract protected function closed($user);
สร้าง testWebSocketChat.php
<?php
require './websockets.php';
class testWebSocketChat extends WebSocketServer {
protected function process ($user, $message) {
}
protected function connected ($user) {
}
protected function closed ($user) {
}
}
$testWebSocketChat = new testWebSocketChat("127.0.0.1","9000");
try {
$testWebSocketChat->run();
}
catch (Exception $e) {
$testWebSocketChat->stdout($e->getMessage());
}
จะอธิบายทีละขั้น ดังนี้
- require ไฟล์ของ Class WebSocketServer เข้ามา
- สร้าง function ที่เป็น abstract ทั้งหมดเอาไว้ และจะอธิบายว่าแต่ละกันทำอะไรบ้างในขั้นตอนที่ 2
- สร้าง Object ของ testWebSocketChat ขึ้นมา พร้อมระบุ ip ของ Server เราในที่นี้คือเครื่องของเราเองนั่นคือ 127.0.0.1 พร้อม Port ที่ต้องการจะใช้เชื่อมต่อ Socket กันซึ้งผมกำหนดไปเป็น 9000 (ตัวอย่างไฟล์การทำงานของต้นฉบับก็ใช้ port นี้เลยใช้ตามไม่มีเหตุผลอื่น ฮาๆๆๆ) ซึ้งการกำหนดนี้จะเข้าไปทำงานที่ __construct ในไฟล์ websockets.php ซึ้งมันทำงานยังไงก็ตามเข้าไปดูได้เลยจ้า
- และใช้คำสั่ง run() เพื่อเริ่มกระบวนการทำงาน
ขั้นตอนที่ 2
เราจะ Implement function connected กันก่อนซึ้งจะเป็นไปตามนี้คือ
- เมื่อมี user connect เข้ามานั้นจะทำการแจ้งเตือนให้กับทุกคนที่อยู่ในห้อง Chat (ยกเว้นตัวเราเอง)
- function connect มีการ pass parameter ที่ชื่อ $user คือรายละเอียดของ user คนนั้นที่ connect เข้ามา
- $this->users คือ ตัวแปรที่เก็บรายละเอียดของ User ทุกๆคน ที่ Connect เข้ามายัง Process Socket ของเรา ซึ้งจะเป็น Array
- $this->send( <user> , <data> ) คือคำสั้งที่ใช้ส่งข้อมูลไปยัง user คนนั้นๆ ซึ้นมันทำงานยังไงนั้น ....... ยาวเลยบ่องตง ตามเข้าไปดูเองใน websockets.php เลยจ้า
ดังนั้นเราจะเขียนโปรแกรมอกมาได้ดังนี้
protected function connected ($user) {ภายในส่วนของ data จะส่งข้อควาที่เป็น id และ เวลา ไปด้วยตามขอบเขตที่เขียนเอาไว้ด้วย
foreach ($this->users as $value) {
if ($value != $user)
$this->send($value , "id ".$user->id." (".date("Y-m-d H:i:s").") : Connected");
}
}
ขั้นตอนที่ 3
Implement function closed ก็จะมีรายละเอียดเหมือนๆกับ connected นั่นละครับ เพียงแต่เปลี่ยนคำพูดนิดหน่อยเท่านั้นเอง
protected function closed ($user) {
foreach ($this->users as $value) {
if ($value != $user)
$this->send($value , "id ".$user->id." (".date("Y-m-d H:i:s").") : Disconnect");
}
}
ขั้นตอนที่ 4
Implement function process
- จะทีการ pass parameter เข้า user และ message ที่ถูกส่งมาจาก Client
- เพิ่ม id เข้าไปในข้อความ เพื่อระบุตัวตนได้ตามขอบเขต
- ส่งข้อความไปยังทุกคนยกเว้นตนเอง
protected function process ($user, $message) {
$message = "id ".$user->id." : ".$message;
foreach ($this->users as $key => $value) {
if ($value != $user) {
$this->send($value,$message);
}
}
}
ขั้นตอนที่ 5
จากที่ได้ Implement code ทั้งหมดไปแล้ว ซึ้งง่ายมากๆ ก็จะถึงตอนที่เราจะทำการรัน Daemon Process ของโปรแกรมที่เราเขียนกันแล้ว ซึ้งง่ายมากๆ โดยไปยัง path ที่เขียนไฟล์ testWebSocketChat.php และใช้คำสั่ง.....
php testWebSocketChat.php
เท่านี้ก็เรียบร้อย รอให้บริการกับทาง Client ที่จะเข้ามายัง Process ได้เลย และสำหรับการ Implement ทางฟั่ง Server ก็มีเท่านี้ ส่วนทางด้าน Client นั้นจะขอยกเอาไปเล่ากันต่อบทความต่อไปนะครับ แต่จะทิ้ง code ทาง client เอาไว้ให้แล้วเอาไปดูกัน เพราะมันเข้าใจได้โดยที่ไม่ต้องอธิบาย แต่สำหรับคนที่ไม่เข้าใจก็รอในบทความต่อไปเลยครับ
ไฟล์ client.html
<!doctype html>
<html>
<head>
<meta charset='UTF-8' />
<title>WebSocket4Chat</title>
<style>
input, textarea {border:1px solid #CCC;margin:5px;padding:5px}
.main {max-width:800px;margin:auto}
#chatbox {width:100%;height:400px;font-size: 15px;}
#message {width:100%;line-height:30px;font-size: 15px;}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
function getDate () {
var objToday = new Date(),
weekday = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'),
dayOfWeek = weekday[objToday.getDay()],
domEnder = new Array( 'th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th' ),
dayOfMonth = today + (objToday.getDate() < 10) ? '0' + objToday.getDate() + domEnder[objToday.getDate()] : objToday.getDate() + domEnder[parseFloat(("" + objToday.getDate()).substr(("" + objToday.getDate()).length - 1))],
months = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'),
curMonth = months[objToday.getMonth()],
curYear = objToday.getFullYear(),
curHour = objToday.getHours() > 12 ? objToday.getHours() - 12 : (objToday.getHours() < 10 ? "0" + objToday.getHours() : objToday.getHours()),
curMinute = objToday.getMinutes() < 10 ? "0" + objToday.getMinutes() : objToday.getMinutes(),
curSeconds = objToday.getSeconds() < 10 ? "0" + objToday.getSeconds() : objToday.getSeconds(),
curMeridiem = objToday.getHours() > 12 ? "PM" : "AM";
var today = curHour + ":" + curMinute + ":" + curSeconds + curMeridiem + "," + dayOfMonth + " " + curMonth + ", " + curYear;
return today;
}
function writeChatbox( text ) {
$chatbox = $('#chatbox');
//Add text to chatbox
$chatbox.append(($chatbox.val()?"\n":'')+text);
//Autoscroll
$chatbox[0].scrollTop = $chatbox[0].scrollHeight - $chatbox[0].clientHeight;
}
function checkStatusConnectSocket(state) {
if (state == 1) {
return 'You : Connected ('+getDate()+')';
}
else if (state == 3) {
return 'You : Disconnected ('+getDate()+')';
}
else if (state == 0) {
return 'You : Init Socket ('+getDate()+')';
}
}
function init() {
var host = "ws://127.0.0.1:9000/"; // SET THIS TO YOUR SERVER
try {
socket = new WebSocket(host);
socket.onopen = function(data) {
writeChatbox (checkStatusConnectSocket(socket.readyState));
};
socket.onmessage = function(data) {
// console.log(data);
writeChatbox (data.data);
};
socket.onclose = function(data) {
writeChatbox (checkStatusConnectSocket(socket.readyState));
};
}
catch (ex) {
writeChatbox (ex);
}
}
function send(data) {
if(!data) {
alert("Message can not be empty");
return;
}
try {
socket.send(data);
} catch(ex) {
writeChatbox ('Can not send Data to server ('+ex+')');
}
}
$(document).ready(function() {
$('#message').keypress(function(e) {
if ( e.keyCode == 13 && this.value ) {
writeChatbox( 'You: ' + this.value );
send( this.value );
$(this).val('');
$(this).focus();
}
});
init();
});
</script>
</head>
<body>
<div class="main">
<textarea id='chatbox' name='chatbox' readonly='readonly'></textarea>
<input type='text' id='message' name='message' />
</div>
</body>
</html>
วันอังคารที่ 17 มีนาคม พ.ศ. 2558
WebSockets กับเว็บแชทขั้นพื้นฐาน ตอนที่ 1
WebSockets
ตอนที่ 2 http://aobkung.blogspot.com/2015/03/websockets-2.htmlตอนที่ 3 http://aobkung.blogspot.com/2015/05/websockets-3.html
ถ้าจะให้พูดง่ายๆ คำพูดไม่สวยหรูก็คือ เป็นสิ่งหนึ่งที่ทำให้ Client สามารถรับอะไรต่างๆนาๆที่ server อยากจะให้โดยที่ไม่ต้องส่ง requests ไปยัง server ว่ามีอะไรจะให้ไหม ถ้ามีส่งมาน๊ะ อะไรประมานนั้น จึงประหยัดทั้งเวลาที่ใช้รอในการ requests ลดการทำงานของ server ลง เพราะไม่ต้องรับ requests ถี่ๆ(บางคนใช้วิธีการตั้งเวลาเพื่อขอรีเควสเรื่อยๆอาจจะทุกๆ 2 วินาที) เป็นต้น
แต่ถ้าให้พูดถึงการทำโปรแกรมแชท , ทำ notification หรืออะไรก็แล้วแต่ที่เป็นไปในลักษณะ real time ก็มีวิธีที่จะนำไปใช้ได้อยู่คร่าวๆดังนี้
- Long Polling
- Server-Sent Event
- Websockets
Ajax Long Polling
client จะทำการส่ง requests ผ่าน http ไปยัง server จากนั้นเมื่อ server มี state ใหม่ๆหรือมี new information ที่จะต้องการส่งไปยัง Client ก็จะส่งข้อมูลมาให้ (โดยที่ไม่ต้องร้องขอข้อมูลไปบ่อยๆ แต่ร้องขอไปครั้งเดียว เมื่อมีอะไรเกิดขึ้นก็จะบอก) จึงต่างจาก Ajax Ploling ธรรมดา
Server-Sent Event
เมื่อ Client ส่ง request ไปยัง server ผ่าน HTTP ทาง sever จะสร้าง Process ขึ้นมาพร้อมกับการลืบค้น State ใหม่ๆกับ Database และส่งกลับมายัง Client รับ State ใหม่ๆไป ซึ้งจะเห็นได้จะเป็น Real-time traffic จาก server ไปสู่ client แต่วิธีการเช่นนี้จะมี Default delay อยู่ที่ 3 วินาที
Websockets
จะเป็นการที่ Client กับ Server เปิดการเชื่มต่อกัน ถ้าพูดให้เห็นภาพ เหมือนกับการที่เรา(Server)เอาเชือกมาผูกกับคนอื่นๆ(Client) และเชื่อมีแรงตึง ถ้าเชือกหย่อนเมื่อไหร่แปลว่าคนๆนั้นไม่ได้เชื่อมต่อ และการส่งของให้กันก็ร้อยผ่านเชือกไป เมื่อของไปกระทบตัวคนๆนั้นก็จะรู้ตัวและหยิบของไป ประมานนั้น ซึ้งไอ้เจ้า Web Sockets นี้จะสร้าง Process 1 Process ขึ้นมาด้วยการใช้คำสั่งของ Server เพื่อเป็น Process ที่ใช้ในการรองรับการเชื่มต่อ รอรับข้อมูล ส่งข้อมูล (Process เดียวบริการทุก Client) มันจึงเป็นเหตุผลให้มีสรรพคุณที่ได้โม้เอาไว้ในย่อหน้าแรก และนี่ละคือพระเอกของเรา
Conclusion
| .. | Long-polling | Server-Sent Events | WebSockets |
|---|---|---|---|
| Browser support | Supported by the most of currently used browsers | Supported by Chrome 9+, Firefox 6+, Opera 11+, Safari 5+ | The latest hybi-10 protocol supported by Chrome 14, Firefox 7 betas, hybi-07 supported by Firefox 6 |
| Server-loading | Takes little of CPU resources, but creates idle processes per user expending server memory | Works in many ways as long-polling, unless SSE doesn’t need to close connection every time when response is sent | The best possible solution. Server has the only process serving any requests. No loops, memory/CPU expense per client, but per client action |
| Client-loading | Depends on implementation, though it always an asynchronous process. | Natively implemented in the browser, takes minimum resources | Natively implemented in the browser, takes minimum resources |
| Timeliness | Near real-time, though black out period between sending response and making a new request adds some delay | Default delay 3 sec., but can be changed | True real-time |
| Complexity of implementation | Very easy | Even easier | Requires an EventMachine server and a custom port being open |
จากตารางเปรียบเทียบจะเห็นได้ว่า WebSockets นั้น ด้าน server-loading นั้นเป็น The best possible solution เลยทีเดียวและ only process serving any requests ส่วนทางด้าน Timeliness นั้นก็คงพูดได้แค่ว่า True real-time ปัจจุบันเลยละจร้าาาาา
ข้อมูลอ้างอิง
งั้นเรามาเริ่มการ Impliment กันเลยดีกว่า ซึ้งเราจะทำด้วย ภาษา php ในฟั่งของ Server (ที่ใช้ Run เพื่อรองรับการเชื่อมต่อ ) และ javascript ใช้สำหรับ Client เพื่อเชื่อมต่อ ส่งข้อมูล และรับข้อมูล
(ผู้อ่านท่านไหนไม่คล่องเรื่อง javascript ajax jquery ก็ศึกษาเพิ่มเติมตามเว็บทั่วๆไป เพราะจะอธิบายทุกบรรทัดคงไม่ไหว )
.
.
.
.
.
.
.
แต่สำหรับตอนที่ 1 ขอพักเอาไว้เท่านี้ก่อนครับ บทความต่อไปในตอนที่ 2 จะเป็นการ impliment ครับ
วันเสาร์ที่ 21 กุมภาพันธ์ พ.ศ. 2558
มารู้จัก Genetic Algorithm พื้นฐานกัน มันกว่าที่คิด
Genetic Algorithm
ขั้นตอนวิธีเชิงพันธุกรรม (Genetic Algorithm – GA) เป็นเทคนิคทางปัญญาประดิษฐ์ (AI : artificial intelligence) อย่างหนึ่งที่ใช้ในการค้นหา การเพิ่มประสิทธิภาพ และการเรียนรู้ (Search, Optimization, and Learning) ด้วยการเลียนแบบทฤษฎีการวิวัฒนาการทางธรรมชาติ โดยขั้นตอนวิธีเชิงพันธุกรรมมีจุดเด่นในด้านความทนทานต่อความผิดพลาดในการค้นหาคำตอบจากแหล่งข้อมูลที่มีความซับซ้อนและยากที่จะสร้างแบบจำลองด้วยสมการคณิตศาสตร์ เนื่องจากเป็นกระบวนการค้นหาที่ไม่มีความเฉพาะเจาะจงกับแบบจำลองหรือลักษณะเฉพาะของข้อมูลแบบใดแบบหนึ่ง ด้วยเหตุนี้ขั้นตอนวิธีเชิงพันธุกรรมจึงถูกนำมาประยุกต์ใช้ในการแก้ปัญหาได้หลากหลายรูปแบบ
- ตั้งแต่การจัดตารางเวลา (Timetable Scheduling)
- การออกแบบระบบควบคุมอัตโนมัติ (Control System Design)
- การออกแบบเพื่อเพิ่มประสิทธิภาพของระบบท่อส่งก๊าซ (Gas Pipeline Optimization)
- การพัฒนาระบบปัญญาประดิษฐ์ (AI : artificial intelligence) ที่สามารถเรียนรู้จากสภาพแวดล้อมได้ (Genetic Based Machine Learning)
เป็นต้น
โดยหลักการของขั้นตอนวิธีเชิงพันธุกรรม เป็นการเลียนแบบกระบวนการวิวัฒนาการตามธรรมชาติ เพื่อพัฒนาหรือทำการ
“วิวัฒนาการ”คำตอบที่ดีที่สุดในการแก้ปัญหา
ที่มา : https://kapitaennem0.wordpress.com/2013/07/17/genetic-algorithm/
(ผู้เขียนบล๊อกนี้อธิบายได้ดี ผมจึงนำมานำเสนอต่อ)
Genetic Algorithm มีอะไรบ้าง
สำหรับองค์ประกอบหลักๆ ของ Genetic Algorithm มีดังนี้
1. Chromosome Encoding
2. Initial Population
3. Fitness Function
4. Genetic Operator -> Selection, Crossover, Mutation
5. Replacement
1. Chromosome Encoding
เป็นขั้นตอนในการแปลงปัญหาให้เป็น Chromosome หรือพูดง่ายๆคือ รูปแบบหรือรูปร่างของข้อมูลของปัญหานั้นๆ
เช่น ปัญหา Binary Encoding จะมีลักษณะของ Chromosome เป็นดังนี้
1001 1011นิยามให้มันมี 0 หรือ 1 และมียีนในแต่ละ Chromosome ทั้งหมด 8 ตัว
2. Initial Population
คือการ สร้างประชากรขึ้นมาโดยการสุ่มสร้างหรือสุ่มเลือกขึ้นมา และการสร้างจำนวนประชากร(จำนวน Chromosome) จะเป็น Parameter ของ Algorithm
เช่น เราจะสร้างประชากรขึ้นมา 4 Chromosome โดยการสุ่มเลข 0 , 1 เข้าไปใน Chromosome
A: 0110 0100
B: 0010 1011
C: 1110 1101
D: 1101 1001
3. Fitness Function
คือสิ่งที่จะใช้ในการการประเมินค่าความเหมาะสม หรือ คะแนนของประชากรนั้นๆ เพื่อใช้ในการพิจารณาว่า โครโมโซมตัวนั้น เหมาะหรือไม่ที่จะนำมาใช้สืบทอดพันธุกรรมสำหรับสร้างโครโมโซมรุ่มใหม่หรือไม่ โดยสมการหรือวิธีการในการคิดค่า Fitness นั้นขึ้นอยู่กับปัญหานั้นๆ
เช่น ในปัญหา Binary Encoding เราจะให้ Chromosome ที่มีเลข 1 จะนับเป็น 1 คะแนน
A: 0110 0100 = 3
B: 0010 1011 = 4
C: 1110 1101 = 6
D: 1101 1001 = 5
4. Genetic Operator
จะให้พูดง่ายๆในขั้นตอนนี้คือ เป็นวิธีปรับเปลี่ยนองค์ประกอบของ Chromosome ซึ้งจะแบ่งออกเป็น 3 ส่วนได้แก่
1 Selection
เพื่อให้เกิดการอยู่รอดของสิ่งมีชีวิต จึงต้องทำการคัดเลือกประชากรบางส่วนเพื่อใช้ในการสืบทอดในรุ่นถัดไป ซึ้งในที่นี้คือการคัดเลือก Chromosome ที่จะใช้ในการทำขั้นตอน Genetic ในขั้นตอนถัดไป โดยวิธีการคัดเลือกนั้นก็มีมากมายหลายอย่าง เช่น
- Roulette Wheel
- Ranking
- Tournament
- Elitist
- Steady State
เป็นต้น
โดยปัญหา Binary Encoding นั้นเราจะใช้วิธีการคัดเลือกทั้งหมด (ง่ายดี) และสำหรับการ Crossover จะใช้ค่า Fitness ที่ดีที่สุดผสมกัน
2 Crossover
เป็นกระบวนการในการนำ 2 Chromosome มาผสมกันกันเพื่อให้ได้ Chromosome ใหม่ๆเกิดขึ้น
และสำหรับ ปัญหา Binary Encoding เราจะใช้วิธีที่ง่ายที่สุดคือ แบ่งครึ่ง Chromosome ระหว่าง 2 Chromosome และนำมาผสมกัน
C: 1110 1101 = 6ดังนั้น C กับ D , A กับ B จะ Crossover กัน
D: 1101 1001 = 5
B: 0010 1011 = 4
A: 0110 0100 = 3
C' : 1110 / 10013 Mutation
D' : 1101 / 1101
B' : 0010 / 0100
A' : 0110 / 1011
คือการทำการเปลี่ยนแปลงคุณลักษณะภายใน Chromosome ในบางตำแหน่งของรุ่นลูกเพื่อให้เกิดลักษณะใหม่ๆเกิดขึ้น เช่น จากตัวอย่าง ในตำแหน่งยีนที่ 7 สิ่งใดมีค่าเป็น 0 ให้เปลี่ยนเป็น 1 ทั้งหมด
C' : 1110 / 10115. Replacement
D' : 1101 / 1111
B' : 0010 / 0110
A' : 0110 / 1011
หรือการแทนที่ประชากรรุ่นเก่า ซึ้งวิธีการแทนที่ก็มีหลายหลายรูปแบบมากมาย ไม่ว่าจะเป็นการแทนที่ประชากรรุ่นเก่าทั้งหมด หรือการแทนที่ประชากรเฉพาะบางประชากรเท่านั้นโดยมีวิธีเลือกจากค่า Fitness หรือ ประชากรที่ถูกคัดเลือกจาก Selection แล้ว copy ประชากรที่ไม่ได้ถูกเลือก Selection มาเป็นรุ่นถัดไป บลาๆๆๆๆๆๆๆๆ มากมาย
จากนั้นถ้ายังได้ประชากรรุ่งนที่เรายังไม่ถูกใจ ก็ไปเริ่มกระบวนการใหม่ในขั้นตอนที่ 2 ไปเรื่อยๆ จะกว่าจะถึงจุดที่เราพอใจ แล้วแต่ว่าจุดที่เราพอใจคืออะไร หรือวัดจากอะไรแล้วแต่ความเหมาะสมของปัญหานั้นเอง
ทั้งหมดนี้คือ Genetic Algorithm ขั้นพื้นฐานเท่านั้น ซึ้งเป็น Algorithm ที่ใช้ศิลปะในการทำอีกมากมาย ซึ้งมันทำให้ผมรู้สึกสนุกนั้นเอง ... ผิดพลาดประการก็ขออภัยมา ณ ที่นี้ด้วยครับ หรือมีอะไรเพิ่มเติมก็ comment มาด้านล่างได้เลยครับ
วันศุกร์ที่ 6 กุมภาพันธ์ พ.ศ. 2558
PDO มีมานานแต่หลายคนก็ไม่ใช้ (การ PHP Connect Database แบบ PDO)
ใช้มัน(PDO)ทำไม
ก่อนอื่นการใช้ query แบบเดิมๆที่เราใช้กันจะเป็นในลักษณะนี้
<?php$host = "localhost" ; $username = "xxx" ; // ชื่อผู้ใช้ในการติดต่อกับฐานข้อมูล $password = "xxx" ; // password ในการเชื่อมต่อกับฐานข้อมูล $dbname = "xxx" ; // ชื่อฐานข้อมูล $c = mysql_connect($host,$username,$password); // ติดต่อฐานข้อมูล if (!$c){ echo "<h3>ERROR : ไม่สามารถติดต่อฐานข้อมูลได้</h3>"; exit(); } mysql_query("SET NAMES UTF8"); // สำหรับการติดต่อฐานข้อมูลแบบ UTF8 mysql_select_db($dbname,$c); // สำหรับเลือกชื่อฐานข้อมูลที่ต้องการติดต่อ?>
ต่อมาเราจะลอง query เพื่อตรวจสอบการ login ของ user จากตาราง user
<?php
$sql = "SELECT username FROM user
WHERE username = '$_POST[username]' AND password = '$_POST[password]'";
mysql_query($sql);
?>
ถ้าในกรณีที่เราใส่ข้อมูลใน form กรอก username ด้วยชื่อ username ของใครก็ได้แล้วตามด้วย -- (หมายความว่าเป็นการ comment ของภาษา sql) แล้วพิมพ์ password อะไรลงไปก็ได้
ดังนั้นเราจะได้รูปแบบคำสั้งดังนี้
SELECT username FROM user WHERE username = 'user01' -- AND password = XXXดังนั้นเงื่อนไขจะเป็นจริงตลอด จึง login เข้าได้โดยไม่ต้องรู้ password ก็ได้
แล้วใช้ PDO ยังไงหว่า
ดังนั้นเราจึงมาเลือกวิธีการแบบ PDO กันดีกว่า โดยจะเป็นไปในลักษณะนี้
<?php
// ระบุค่า host และชื่อของ database
$dsn = 'mysql:host=localhost;dbname=XXX';
// ระบุ username และ password
$username = 'username';
$password = 'password';
// คือการต่อเข้ากับฐานข้อมูลแบบ UTF-8
$options = array(?>
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
$dbh = new PDO($dsn, $username, $password, $options);
และเมื่อเราทำการ connect เข้ากับ database แล้ว ทีนี้เราจะมาลอง query แบบง่ายๆกันดีกว่า
<?php
// เราจะต้องทำการ prepare คำสั่ง SQL สะก่อน$sth = $dbh->prepare("SELECT username FROM user WHERE username = :username AND password = :password");
// จากนั้นทำการ execute คำสั่ง SQL พร้อมนำข้อมูลที่ต้องการ binding เข้าไปใน ? ที่เราตามที่เราต้องการ โดยที่มันจะทำหน้าที่ตัดข้อความที่ไม่พึงประสงค์ออกไปในเบื้อต้น$result = $sth->execute( array(':username' => $_POST['username'], ':password' => $_POST['password']) );
// ตรวจสอบว่า execute ผ่านหรือไม่if($result) { // ทำการ fetch ค่าออกมาใช้งาน โดย PDO::FETCH_ASSOC คือการใช้ชื่อ colum name เป็น index ของ array $result = $sth->fetch(PDO::FETCH_ASSOC); print_r($result);}
?>
ปลอดภัยกว่ากันตั้งเยอะ ดังนั้นมาใช้ PDO กันเถิดครับ
สมัครสมาชิก:
บทความ (Atom)

















