Quindi Idea è dietro setInterval e Sockets, setInterval è supportato nella maggior parte dei browser e javascript WbsocketApi è supportato in quasi tutti i browser.
Breve panoramica: setInterval () - questo comportamento della funzione segue quando il computer è in modalità sospensione / sospensione / ibernazione viene messo in pausa e quando si è in modalità di risveglio riprende.
Il seguente codice fa quanto segue, all'inizio (forse allo stesso tempo, ma) avvia php server_socket ascoltando le connessioni,
di javascript websocket api invia il timestamp corrente in millisecondi di timestamp Unix in ogni 2 secondi puoi avere 1 secondo dipende da te.
dopo che il socket del server php sta ricevendo questa volta e controlla se ha qualcosa come la volta precedente da confrontare, quando il codice viene istanziato per la prima volta php non ha niente come la volta precedente per confrontarlo con l'ora che è stata inviata dal websocket javascript, quindi php non fa altro che salvare questa volta nella sessione chiamata "prev_time" e attende che i dati di un'altra ora vengano ricevuti dal socket javascript, quindi qui inizia il secondo ciclo. quando il server php inserisce nuovi dati temporali da WebsocketApi javascript controlla che abbia qualcosa di simile al tempo precedente per confrontarli con questi dati temporali appena ricevuti, significa che php controlla se esiste una sessione chiamata 'prev_time', come siamo nel secondo ciclo php scopre che esiste, afferra il suo valore e segue$diff = $new_time - $prev_time
, $ diff sarà di 2 secondi o 2000 millisecondi perché ricorda che il nostro ciclo setInterval si verifica ogni 2 secondi e il formato dell'ora che stiamo inviando è in millisecondi,
di php controlla if($diff<3000)
se la differenza è inferiore a 3000 se sa che l'utente è attivo, di nuovo puoi manipolare questi secondi come desideri, scelgo 3000 perché possibile latenza nella rete che è quasi impossibile ma sai che sono sempre cauto quando si tratta di reti, quindi continuiamo, quando php determina che l'utente è attivo, php reimposta la sessione "prev_time" con il valore di $new_time
cui è stato appena ricevuto e solo a scopo di test invia un messaggio al socket javascript,
ma se $diff
è più di 3000 significa che qualcosa ha messo in pausa il nostro setInterval e c'è solo un modo in cui può succedere e penso che tu sappia già quello che sto dicendo, quindi nella else
logica di ( if($diff<3000)
) puoi disconnettere l'utente distruggendo una sessione specifica e se tu vuoi reindirizzare puoi inviare del testo al socket javacript e creare una logica che verrà eseguita a window.location = "/login"
seconda del testo, ecco qui è il codice:
Innanzitutto è il file index.html solo per caricare javascript:
<html>
<body>
<div id="printer"></div>
<script src="javascript_client_socket.js"></script>
</body>
</html>
allora è javascript non è davvero ben codificato ma puoi capire LEGGI I COMMENTI SONO IMPORTANTI:
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);
};
ora qui fa parte del codice php, non ti preoccupare c'è anche il codice completo ma questa parte è in realtà ciò che fa i lavori sopra menzionati incontrerai anche altre funzioni ma sono per la decodifica e il lavoro con i socket javascript quindi è la cosa giusta qui LEGGI I COMMENTI SONO IMPORTANTI:
<?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);
?>
Ed ecco il codice completo di 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 LEGGI: la
$new_time
variabile è $jsTime
nel codice
crea una cartella e copialo e incollalo nei file esegui php socket con il comando: php -f server_socket.php vai su localhost e testalo aprendo la console per vedere i messaggi dirà "sei attivo" o "non sei attivo" (quando vieni dal sonno); la tua esecuzione avverrà quando l'utente verrà dallo stato di sospensione non quando è in stato di sonno, poiché in quel momento tutto viene memorizzato nella cache nel file di paging (windows) o in swap (linux)