Vì vậy, Idea đứng sau setInterval và Sockets, setInterval được hỗ trợ trong hầu hết các trình duyệt và WbsocketApi javascript được hỗ trợ trong hầu hết mọi trình duyệt.
Tổng quan ngắn gọn: setInterval () - hành vi chức năng này tuân theo khi máy tính của bạn ở chế độ ngủ / treo / ngủ đông, nó bị tạm dừng và khi bạn ở chế độ thức tỉnh, nó sẽ tự hoạt động trở lại.
Đoạn mã sau thực hiện như sau, lúc đầu (có thể cùng lúc nhưng) nó khởi động php server_socket lắng nghe các kết nối,
so với javascript websocket api gửi dấu thời gian hiện tại trong dấu thời gian Unix mili giây trong mỗi 2 giây bạn có thể có 1 giây tùy thuộc vào bạn.
Sau đó, ổ cắm máy chủ php sẽ nhận được thời gian này và kiểm tra xem nó có gì giống với lần trước không, khi mã được khởi tạo lần đầu tiên php không có gì giống như lần trước để so sánh với thời gian được gửi từ websocket javascript, vì vậy php không làm gì ngoài việc tiết kiệm thời gian này trong phiên gọi là 'trước_ thời gian' và chờ dữ liệu thời gian khác được nhận từ ổ cắm javascript, vì vậy ở đây bắt đầu chu kỳ thứ hai. Khi máy chủ php cắm dữ liệu thời gian mới từ javascript WebsocketApi, nó sẽ kiểm tra nó có bất cứ thứ gì giống như lần trước để so sánh với dữ liệu thời gian mới nhận này không, có nghĩa là php kiểm tra nếu phiên có tên là 'trước_ tồn tại', vì chúng ta đang ở trong chu kỳ thứ hai php phát hiện ra rằng nó tồn tại, lấy giá trị của nó và làm theo$diff = $new_time - $prev_time
, $ diff sẽ là 2 giây hoặc 2000 milis giây vì hãy nhớ chu kỳ setInterval của chúng tôi diễn ra trong mỗi 2 giây và định dạng thời gian chúng tôi đang gửi là tính bằng milisecond,
hơn kiểm tra php if($diff<3000)
nếu chênh lệch nhỏ hơn 3000 nếu biết rằng người dùng đang hoạt động, một lần nữa bạn có thể thao tác giây này theo ý muốn, tôi chọn 3000 vì độ trễ có thể xảy ra trong mạng gần như không thể nhưng bạn biết tôi luôn thận trọng khi nó liên quan đến các mạng, vì vậy hãy tiếp tục, khi php xác định rằng người dùng đang hoạt động php chỉ cần đặt lại phiên 'trước_ thời gian' với giá trị $new_time
mới nhận được và chỉ nhằm mục đích thử nghiệm, nó sẽ gửi tin nhắn trở lại ổ cắm javascript,
nhưng nếu $diff
nhiều hơn 3000 thì có nghĩa là có gì đó đã tạm dừng setInterval của chúng tôi và chỉ có cách nó có thể xảy ra và tôi nghĩ bạn đã biết tôi đang nói gì, vì vậy theo else
logic của ( if($diff<3000)
) bạn có thể đăng xuất người dùng bằng cách hủy phiên cụ thể và nếu bạn muốn chuyển hướng bạn có thể gửi một số văn bản đến ổ cắm javacript và tạo một logic sẽ thực thi window.location = "/login"
tùy thuộc vào văn bản, đó là mã:
Đầu tiên, nó là tệp index.html để tải javascript:
<html>
<body>
<div id="printer"></div>
<script src="javascript_client_socket.js"></script>
</body>
</html>
Sau đó, nó là javascript, nó không thực sự được mã hóa đẹp nhưng bạn có thể tìm ra Ý KIẾN ĐỌC NHỮNG ĐIỀU QUAN TRỌNG:
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);
};
Bây giờ đây là một phần của mã php, đừng lo lắng vì cũng có mã đầy đủ nhưng phần này thực sự là những công việc được đề cập ở trên, bạn cũng sẽ gặp các chức năng khác nhưng chúng là để giải mã và làm việc với các ổ cắm javascript nên thực tế là đúng Ở đây ĐỌC Ý KIẾN HỌ LÀ QUAN TRỌNG:
<?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);
?>
Và đây là mã đầy đủ của 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;
}
LƯU Ý ĐỌC CNTT:
$new_time
biến nằm $jsTime
trong Code
tạo thư mục và chỉ cần sao chép và dán tệp này vào các tệp chạy php socket bằng lệnh: php -f server_socket.php đi đến localhost và kiểm tra bảng điều khiển mở để xem các thông báo sẽ cho biết "bạn đang hoạt động" hoặc "bạn không hoạt động" (khi bạn đi từ giấc ngủ); giám đốc điều hành của bạn sẽ xảy ra khi người dùng đến từ giấc ngủ chứ không phải khi họ đang ngủ vì tại thời điểm đó, mọi thứ được lưu trữ trong pagefile (windows) hoặc trao đổi (linux)