Entonces Idea está detrás de setInterval y Sockets, setInterval es compatible con la mayoría de los navegadores y javascript WbsocketApi es compatible con casi todos los navegadores.
Breve descripción general: setInterval (): este comportamiento de la función se produce cuando la computadora está en modo de suspensión / suspensión / hibernación, está en pausa y cuando está en modo de despertar se reanuda.
El siguiente código hace lo siguiente, al principio (quizás al mismo tiempo, pero) comienza php server_socket escuchando las conexiones,
que la API websocket de javascript envía la marca de tiempo actual en milisegundos de marca de tiempo de Unix en cada 2 segundos que puede tener 1 segundo, depende de usted.
después de que el socket del servidor php está obteniendo este tiempo y comprueba si tiene algo como el tiempo anterior para comparar, cuando el código se instancia por primera vez, php no tiene nada como el tiempo anterior para compararlo con el tiempo enviado desde javascript websocket, entonces php no hace más que guardar este tiempo en la sesión llamada 'prev_time' y espera a que se reciban datos de otro momento desde el socket de JavaScript, por lo que aquí comienza el segundo ciclo. cuando el servidor php toma nuevos datos de tiempo de javascript WebsocketApi comprueba que tiene algo como el tiempo anterior para comparar con estos datos de tiempo recién recibidos, significa que php comprueba si existe una sesión llamada 'prev_time', ya que estamos en el segundo ciclo php descubre que existe, toma su valor y sigue$diff = $new_time - $prev_time
, $ diff será de 2 segundos o 2000 milisegundos porque recuerde que nuestro ciclo setInterval ocurre en cada 2 segundos y el formato de tiempo que enviamos está en milisegundos,
que php comprueba if($diff<3000)
si la diferencia es menor a 3000 si es que sabe que el usuario está activo, nuevamente puede manipular estos segundos como lo desee, elijo 3000 porque es posible una latencia en la red que es casi imposible, pero sabe que siempre soy cauteloso cuando se trata de redes, así que continuemos, cuando php determina que el usuario está activo, php simplemente restablece la sesión 'prev_time' con el valor $new_time
que se recibió recientemente y solo con fines de prueba, envía un mensaje de vuelta al socket de JavaScript,
pero si $diff
es más de 3000 significa que algo pausó nuestro setInterval y solo puede suceder y creo que ya sabe lo que estoy diciendo, por lo que en la else
lógica de ( if($diff<3000)
) puede cerrar la sesión del usuario destruyendo una sesión específica y si desea redirigir, puede enviar algo de texto al socket javacript y crear una lógica que se ejecutará window.location = "/login"
dependiendo del texto, aquí está el código:
Primero es el archivo index.html solo para cargar javascript:
<html>
<body>
<div id="printer"></div>
<script src="javascript_client_socket.js"></script>
</body>
</html>
entonces es javascript, no está muy bien codificado, pero puedes descubrir LEER COMENTARIOS QUE SON IMPORTANTES:
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);
};
ahora aquí es parte del código php, no te preocupes, también hay un código completo, pero esta parte es en realidad lo que hace los trabajos mencionados anteriormente, también cumplirás otras funciones, pero son para decodificar y trabajar con sockets javascript, por lo que es correcto aquí LEER COMENTARIOS SON IMPORTANTES:
<?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);
?>
Y aquí está el código completo de 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;
}
NOTA LEER: la
$new_time
variable está $jsTime
en el código
cree la carpeta y simplemente copie y pegue esto en los archivos ejecute php socket con el comando: php -f server_socket.php vaya al localhost y pruébelo abra la consola para ver mensajes que dirá "usted está activo" o "no está activo" (cuando vienes de dormir); su ejecución ocurrirá cuando el usuario salga del modo de suspensión, no cuando esté en reposo porque en ese momento todo se almacena en caché en el archivo de paginación (windows) o en el intercambio (linux)