ดังนั้น Idea อยู่เบื้องหลัง setInterval และ Sockets สนับสนุน setInterval ในเบราว์เซอร์ส่วนใหญ่และจาวาสคริปต์ WbsocketApi รองรับเกือบทุกเบราว์เซอร์
ภาพรวมโดยย่อ: setInterval () - ลักษณะการทำงานของฟังก์ชั่นนี้จะเกิดขึ้นเมื่อคอมพิวเตอร์ของคุณอยู่ในโหมดสลีป / พัก / โหมดไฮเบอร์เนตจะถูกหยุดชั่วคราวและเมื่อคุณอยู่ในโหมดปลุก
รหัสต่อไปนี้ทำดังต่อไปนี้ในตอนแรก (อาจในเวลาเดียวกัน แต่) มันเริ่ม php server_socket ฟังการเชื่อมต่อ
กว่า javascript websocket api ส่งการประทับเวลาปัจจุบันเป็น Unix มิลลิวินาทีการประทับเวลาในทุก 2 วินาทีคุณสามารถมี 1 วินาทีขึ้นอยู่กับคุณ
หลังจากนั้นซ็อกเก็ตเซิร์ฟเวอร์ php จะได้รับในเวลานี้และตรวจสอบว่ามีอะไรที่เหมือนกับเวลาก่อนหน้าเพื่อเปรียบเทียบเมื่อรหัสเป็นอินสแตนซ์แรก php ไม่มีอะไรที่เหมือนกับเวลาก่อนหน้าเพื่อเปรียบเทียบกับเวลาที่ถูกส่งจาก javascript websocket ดังนั้น php ไม่ทำอะไรเลยนอกจากบันทึกเวลานี้ในเซสชันที่เรียกว่า 'prev_time' และรอให้มีการรับข้อมูลเวลาอื่นจากซ็อกเก็ต javascript ดังนั้นที่นี่จะเริ่มรอบที่สอง เมื่อเซิร์ฟเวอร์ซ็อกเก็ต php ข้อมูลเวลาใหม่จาก javascript WebsocketApi ตรวจสอบว่ามีอะไรที่เหมือนกับเวลาก่อนหน้าเพื่อเปรียบเทียบกับข้อมูลเวลาที่ได้รับใหม่นี้หมายความว่า php ตรวจสอบว่าเซสชันที่เรียกว่า 'prev_time' มีอยู่ในขณะที่เราอยู่ในรอบที่สอง มีอยู่แล้วคว้ามันคุ้มค่าและทำตาม$diff = $new_time - $prev_time
, $ diff จะเป็น 2 วินาทีหรือ 2,000 miliseconds เพราะจำวงจร setInterval ของเราเกิดขึ้นในทุก ๆ 2 วินาทีและรูปแบบเวลาที่เราส่งเป็นมิลลิวินาที
กว่า php ตรวจสอบif($diff<3000)
ว่ามีความแตกต่างน้อยกว่า 3000 หรือไม่หากรู้ว่าผู้ใช้นั้นทำงานอยู่คุณสามารถจัดการกับวินาทีนี้ได้ตามที่คุณต้องการฉันเลือก 3000 เพราะเวลาแฝงที่เป็นไปได้ในเครือข่ายซึ่งแทบจะเป็นไปไม่ได้ แต่คุณรู้ว่า มันมาถึงเครือข่ายดังนั้นเราจะดำเนินการต่อเมื่อ php พิจารณาว่าผู้ใช้นั้นเป็น php ที่เพิ่งรีเซ็ตเซสชั่น 'prev_time' ด้วยค่า$new_time
ที่ได้รับใหม่และเพื่อการทดสอบเท่านั้นมันจะส่งข้อความกลับไปยังซ็อกเก็ต javascript
แต่ถ้า$diff
มีมากกว่า 3000 นั่นหมายความว่ามีบางสิ่งที่หยุด setInterval ของเราและมีวิธีเดียวที่มันสามารถเกิดขึ้นได้และฉันคิดว่าคุณรู้แล้วว่าฉันกำลังพูดอะไรอยู่ดังนั้นในelse
ตรรกะของ ( if($diff<3000)
) คุณสามารถออกจากระบบผู้ใช้ ต้องการเปลี่ยนเส้นทางคุณสามารถส่งข้อความไปยังซ็อกเก็ต javacript และสร้างตรรกะซึ่งจะดำเนินการwindow.location = "/login"
ขึ้นอยู่กับข้อความนั่นคือนี่คือรหัส:
ก่อนอื่นก็คือไฟล์ index.html เพื่อโหลด javascript:
<html>
<body>
<div id="printer"></div>
<script src="javascript_client_socket.js"></script>
</body>
</html>
แล้วมันเป็นจาวาสคริปต์มันไม่ได้เข้ารหัสอย่างสวยงามจริงๆ แต่คุณสามารถหาอ่านความคิดเห็นพวกเขามีความสำคัญ:
var socket = new WebSocket('ws://localhost:34237'); // connecting to socket
// Open the socket
socket.onopen = function(event) { // detecting when connection is established
setInterval(function(){ //seting interval for 2 seconds
var date = new Date(); //grabing current date
var nowtime = Date.parse(date); // parisng it in miliseconds
var msg = 'I am the client.'; //jsut testing message
// Send an initial message
socket.send(nowtime); //sending the time to php socket
},2000);
};
// Listen for messages
socket.onmessage = function(event) { //print text which will be sent by php socket
console.log('php: ' + event.data);
};
// Listen for socket closes
socket.onclose = function(event) {
console.log('Client notified socket has closed', event);
};
ตอนนี้ที่นี่เป็นส่วนหนึ่งของรหัส php ไม่ต้องกังวลว่าจะมีรหัสเต็มเช่นกัน แต่ส่วนนี้เป็นสิ่งที่ไม่ได้กล่าวถึงข้างต้นงานที่คุณจะได้พบกับฟังก์ชั่นอื่น ๆ แต่พวกเขามีไว้สำหรับถอดรหัสและทำงานร่วมกับซ็อกเก็ตจาวาสคริปต์ อ่านความคิดเห็นที่นี่พวกเขามีความสำคัญ:
<?php
$decoded_data = unmask($data /* $data is actual data received from javascript socket */); //grabbing data and unmasking it | unmasking is for javascript sockets don't mind this
print("< ".$decoded_data."\n");
$response = strrev($decoded_data);
$jsTime = (int) $decoded_data; /* time sent by javascript in MILISECONDS IN UNIX FORMAT */
if (isset($_SESSION['prev_time'])) { /** check if we have stored previous time in the session */
$prev_time = (int) $_SESSION['prev_time']; /** grabbing the previous time from session */
$diff = $jsTime-$prev_time; /** getting the difference newly sent time and previous time by subtracting */
print("$jsTime - $prev_time = $diff"); /** printing the difference */
if($diff<3000){ /** checking if difference is less than 3 second if it is it means pc was not at sleep
*** you can manipulate and have for example 1 second = 1000ms */
socket_write($client,encode("You are active! your pc is awakend"));
$_SESSION['prev_time'] = $jsTime; /** saving newly sent time as previous time for future testing whcih will happen in two seconds in our case*/
}else { /** if it is more than 3 seconds it means that javascript setInterval function was paused and resumed after 3 seconds
** So it means that it was at sleep because when your PC is at sleep/suspended/hibernate mode setINterval gets pauesd */
socket_write($client,encode("You are not active! your pc is at sleep"));
$_SESSION['prev_time'] = $jsTime;
}
}else { /** if we have not saved the previous time in session save it */
$_SESSION['prev_time'] = $jsTime;
}
print_r($_SESSION);
?>
และนี่คือรหัสเต็มของ php:
<?php
//Code by: Nabi KAZ <www.nabi.ir>
session_abort();
// set some variables
$host = "127.0.0.1";
$port = 34237;
date_default_timezone_set("UTC");
// don't timeout!
set_time_limit(0);
// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0)or die("Could not create socket\n");
// bind socket to port
$result = socket_bind($socket, $host, $port)or die("Could not bind to socket\n");
// start listening for connections
$result = socket_listen($socket, 20)or die("Could not set up socket listener\n");
$flag_handshake = false;
$client = null;
do {
if (!$client) {
// accept incoming connections
// client another socket to handle communication
$client = socket_accept($socket)or die("Could not accept incoming connection\n");
}
$bytes = @socket_recv($client, $data, 2048, 0);
if ($flag_handshake == false) {
if ((int)$bytes == 0)
continue;
//print("Handshaking headers from client: ".$data."\n");
if (handshake($client, $data, $socket)) {
$flag_handshake = true;
}
}
elseif($flag_handshake == true) {
/*
**** Main section for detectin sleep or not **
*/
if ($data != "") {
$decoded_data = unmask($data /* $data is actual data received from javascript socket */); //grabbing data and unmasking it | unmasking is for javascript sockets don't mind this
print("< ".$decoded_data."\n");
$response = strrev($decoded_data);
$jsTime = (int) $decoded_data; /* time sent by javascript in MILISECONDS IN UNIX FORMAT */
if (isset($_SESSION['prev_time'])) { /** check if we have stored previous time in the session */
$prev_time = (int) $_SESSION['prev_time']; /** grabbing the previous time from session */
$diff = $jsTime-$prev_time; /** getting the difference newly sent time and previous time by subtracting */
print("$jsTime - $prev_time = $diff"); /** printing the difference */
if($diff<3000){ /** checking if difference is less than 3 second if it is it means pc was not at sleep
*** you can manipulate and have for example 1 second = 1000ms */
socket_write($client,encode("You are active! your pc is awakend"));
$_SESSION['prev_time'] = $jsTime; /** saving newly sent time as previous time for future testing whcih will happen in two seconds in our case*/
}else { /** if it is more than 3 seconds it means that javascript setInterval function was paused and resumed after 3 seconds
** So it means that it was at sleep because when your PC is at sleep/suspended/hibernate mode setINterval gets pauesd */
socket_write($client,encode("You are not active! your pc is at sleep"));
$_SESSION['prev_time'] = $jsTime;
}
}else { /** if we have not saved the previous time in session save it */
$_SESSION['prev_time'] = $jsTime;
}
print_r($_SESSION);
/*
**** end of Main section for detectin sleep or not **
*/
}
}
} while (true);
// close sockets
socket_close($client);
socket_close($socket);
$client = null;
$flag_handshake = false;
function handshake($client, $headers, $socket) {
if (preg_match("/Sec-WebSocket-Version: (.*)\r\n/", $headers, $match))
$version = $match[1];
else {
print("The client doesn't support WebSocket");
return false;
}
if ($version == 13) {
// Extract header variables
if (preg_match("/GET (.*) HTTP/", $headers, $match))
$root = $match[1];
if (preg_match("/Host: (.*)\r\n/", $headers, $match))
$host = $match[1];
if (preg_match("/Origin: (.*)\r\n/", $headers, $match))
$origin = $match[1];
if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $headers, $match))
$key = $match[1];
$acceptKey = $key.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
$acceptKey = base64_encode(sha1($acceptKey, true));
$upgrade = "HTTP/1.1 101 Switching Protocols\r\n".
"Upgrade: websocket\r\n".
"Connection: Upgrade\r\n".
"Sec-WebSocket-Accept: $acceptKey".
"\r\n\r\n";
socket_write($client, $upgrade);
return true;
} else {
print("WebSocket version 13 required (the client supports version {$version})");
return false;
}
}
function unmask($payload) {
$length = ord($payload[1]) & 127;
if ($length == 126) {
$masks = substr($payload, 4, 4);
$data = substr($payload, 8);
}
elseif($length == 127) {
$masks = substr($payload, 10, 4);
$data = substr($payload, 14);
}
else {
$masks = substr($payload, 2, 4);
$data = substr($payload, 6);
}
$text = '';
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i] ^ $masks[$i % 4];
}
return $text;
}
function encode($text) {
// 0x1 text frame (FIN + opcode)
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($text);
if ($length <= 125)
$header = pack('CC', $b1, $length);
elseif($length > 125 && $length < 65536)$header = pack('CCS', $b1, 126, $length);
elseif($length >= 65536)
$header = pack('CCN', $b1, 127, $length);
return $header.$text;
}
หมายเหตุอ่านมัน:
$new_time
ตัวแปรอยู่$jsTime
ในรหัส
สร้างโฟลเดอร์และเพียงคัดลอกและวางในไฟล์ที่เรียกใช้ซ็อกเก็ต php ด้วยคำสั่ง: php -f server_socket.php ไปที่ localhost และทดสอบคอนโซลเปิดเพื่อดูข้อความว่า "คุณกำลังใช้งาน" หรือ "คุณไม่ได้ใช้งาน" (เมื่อคุณมาจากการนอนหลับ); เอ็กซีคิวต์ของคุณจะเกิดขึ้นเมื่อผู้ใช้มาจากโหมดสลีปไม่ใช่เมื่ออยู่ในโหมดสลีปในขณะนั้นทุกอย่างถูกแคชใน pagefile (windows) หรือสลับ (linux)