Donc, Idea est derrière setInterval et Sockets, setInterval est pris en charge dans la plupart des navigateurs et javascript WbsocketApi est pris en charge dans presque tous les navigateurs.
Bref aperçu: setInterval () - ce comportement de fonction suit lorsque votre ordinateur est en mode veille / suspendu / hibernation il est en pause et lorsque vous êtes en mode réveil, il reprend lui-même.
Le code suivant fait ce qui suit, au début (peut-être en même temps mais) il démarre php server_socket en écoutant les connexions,
que javascript websocket api envoie l'horodatage actuel en horodatage Unix millisecondes toutes les 2 secondes, vous pouvez avoir 1 seconde, c'est à vous.
après que le socket du serveur php obtient cette fois-ci et vérifie s'il a quelque chose comme l'heure précédente à comparer, lorsque le code est instancié pour la première fois, php n'a rien de semblable à l'heure précédente pour le comparer à l'heure qui a été envoyée à partir de websocket javascript, donc php ne fait rien mais enregistre ce temps dans la session appelée «prev_time» et attend qu'une autre donnée de temps soit reçue de la socket javascript, donc ici commence le deuxième cycle. lorsque le serveur php charge de nouvelles données temporelles de javascript WebsocketApi, il vérifie qu'il a quelque chose comme l'heure précédente à comparer à ces données temporelles nouvellement reçues, cela signifie que php vérifie si une session appelée 'prev_time' existe, car nous sommes dans le deuxième cycle php découvre que il existe, saisit sa valeur et suit$diff = $new_time - $prev_time
, $ diff sera de 2 secondes ou 2000 millisecondes, car n'oubliez pas que notre cycle setInterval se produit toutes les 2 secondes et que le format d'heure que nous envoyons est en millisecondes,
que php vérifie if($diff<3000)
si la différence est inférieure à 3000 si elle sait que l'utilisateur est actif, encore une fois vous pouvez manipuler ces secondes comme vous le souhaitez, je choisis 3000 car une latence possible dans le réseau qui est presque impossible mais vous savez que je suis toujours prudent quand il s'agit de réseaux, alors continuons, lorsque php détermine que l'utilisateur est actif, php réinitialise simplement la session 'prev_time' avec la valeur $new_time
qui vient d'être reçue et juste à des fins de test, il renvoie un message à la socket javascript,
mais s'il $diff
est supérieur à 3000, cela signifie que quelque chose a interrompu notre setInterval et qu'il n'y a qu'une seule façon que cela puisse se produire et je pense que vous savez déjà ce que je dis, donc dans la else
logique de ( if($diff<3000)
) vous pouvez déconnecter l'utilisateur en détruisant une session spécifique et si vous voulez rediriger vous pouvez envoyer du texte à la socket javacript et créer une logique qui s'exécutera en window.location = "/login"
fonction du texte, ça y est voici le code:
D'abord c'est le fichier index.html juste pour charger javascript:
<html>
<body>
<div id="printer"></div>
<script src="javascript_client_socket.js"></script>
</body>
</html>
alors c'est javascript, il n'est pas vraiment joliment codé mais vous pouvez comprendre LIRE LES COMMENTAIRES ILS SONT IMPORTANT:
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);
};
maintenant, voici une partie du code php, ne vous inquiétez pas, il y a aussi du code complet, mais cette partie est en fait ce qui fait les travaux mentionnés ci-dessus, vous rencontrerez également d'autres fonctions, mais elles sont destinées au décodage et au travail avec des sockets javascript, donc c'est vraiment la bonne chose LISEZ COMMENTAIRES ILS SONT IMPORTANTS:
<?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);
?>
Et voici le code complet 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;
}
NOTE LISEZ-LE: la
$new_time
variable est $jsTime
dans le code
créez un dossier et copiez et collez-le dans des fichiers exécutez php socket avec la commande: php -f server_socket.php allez sur l'hôte local et testez-le pour ouvrir la console pour voir les messages, il dira "vous êtes actif" ou "vous n'êtes pas actif" (quand tu reviens du sommeil); votre exécutable se produira lorsque l'utilisateur sortira du sommeil et non lorsqu'il sera en veille car à ce moment tout est mis en cache dans le fichier d'échange (windows) ou dans swap (linux)