Так что Idea стоит за setInterval и Sockets, setInterval поддерживается в большинстве браузеров, а javascript 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», так как мы во втором цикле php обнаруживает, что он существует, захватывает его значение и делает следующее$diff = $new_time - $prev_time
, $ diff будет 2 секунды или 2000 миллисекунд, потому что помните, что наш цикл 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>
тогда это javascript, он не очень красиво закодирован, но вы можете понять, ЧИТАЙТЕ КОММЕНТАРИИ, ОНИ ВАЖНЫ:
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-кода, не волнуйтесь, там тоже есть полный код, но эта часть на самом деле делает то, что делает вышеупомянутые задания, вы встретите и другие функции, но они предназначены для декодирования и работы с сокетами javascript, так что это действительно правильно здесь ПРОЧИТАЙТЕ КОММЕНТАРИИ, ОНИ ВАЖНЫ:
<?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 socket с помощью команды: php -f server_socket.php перейдите на локальный хост и протестируйте его, откройте консоль, чтобы увидеть сообщения, в которых будет указано «вы активны» или «вы не активны» (когда ты выходишь из сна); ваше выполнение будет происходить, когда пользователь выйдет из спящего режима, а не когда он спит, потому что в этот момент все кэшируется в файл подкачки (windows) или в swap (linux)