따라서 Idea는 setInterval 및 Sockets 뒤에 있으며 setInterval은 대부분의 브라우저에서 지원되며 자바 스크립트 WbsocketApi는 거의 모든 브라우저에서 지원됩니다.
간단한 개요 : setInterval ()-컴퓨터가 절전 / 일시 중지 / 최대 절전 모드 일 때이 함수의 동작은 다음과 같습니다.
다음 코드는 처음에 다음을 수행합니다 (동시에 가능하지만 연결을 수신하는 PHP server_socket을 시작합니다)
javascript websocket보다 api는 2 초마다 유닉스 타임 스탬프 밀리 초로 현재 타임 스탬프를 보냅니다 .1 초는 자신에게 달려 있습니다.
그 후 PHP 서버 소켓 이이 시간을 가져 와서 비교할 이전 시간과 같은 것이 있는지 확인합니다. 코드가 처음 인스턴스화 될 때 PHP에는 이전 시간과 같은 것이 없으므로 Javascript 웹 소켓에서 보낸 시간과 비교할 수 없습니다. 'prev_time'이라는 세션 에서이 시간을 절약하고 Javascript 소켓에서 다른 시간 데이터가 수신 될 때까지 기다리기 때문에 두 번째 사이클이 시작됩니다. 자바 스크립트 WebsocketApi에서 PHP 서버 소켓 새로운 시간 데이터가 새로 수신 된 시간 데이터와 비교하기 위해 이전 시간과 같은 것이 있는지 확인하면 PHP가 두 번째주기와 같이 'prev_time'이라는 세션이 존재하는지 확인합니다. 그것은 존재하고 가치를 잡고 다음을 수행합니다.$diff = $new_time - $prev_time
, $ diff는 2 초 또는 2000 밀리 초입니다. setInterval주기는 2 초마다 발생하며 전송하는 시간 형식은 밀리 초입니다.
php보다 if($diff<3000)
차이가 3000보다 작은 지 확인 하면 사용자가 활성 상태임을 알면 다시이 초를 조작 할 수 있습니다. 네트워크에서 가능한 지연 시간이 거의 불가능하기 때문에 3000을 선택하지만 항상주의해야합니다. PHP는 사용자가 활성화되어 있다고 판단하면 PHP $new_time
는 새로 수신 된 값으로 'prev_time'세션을 재설정 하고 테스트 목적으로 자바 스크립트 소켓으로 메시지를 다시 보냅니다.
그러나 $diff
3000 이상인 경우 무언가가 setInterval을 일시 중지하고 발생할 수있는 방법 만 있고 내가 말하는 것을 이미 알고 있다고 생각하므로 else
( if($diff<3000)
) 의 논리에서 특정 세션을 파괴하여 사용자를 로그 아웃 할 수 있습니다. 리디렉션하려면 텍스트를 javacript 소켓에 보내고 텍스트에 window.location = "/login"
따라 실행할 로직을 만들 수 있습니다. 코드는 다음과 같습니다.
먼저 javascript를로드하는 것은 index.html 파일입니다.
<html>
<body>
<div id="printer"></div>
<script src="javascript_client_socket.js"></script>
</body>
</html>
그렇다면 그것은 실제로 아름답게 코딩되지는 않지만 자바 스크립트이지만 주석 읽기가 중요하다는 것을 알 수 있습니다.
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 -f server_socket.php 다음 명령으로 php socket을 실행하여 파일을 복사하여 파일에 붙여 넣습니다. php -f server_socket.php localhost로 가서 콘솔이 열려 있는지 테스트합니다. (잠에서 hen을 때); 귀하의 executin은 사용자가 잠 들어있을 때가 아닌 잠 들어있을 때 발생합니다.이 순간 모든 것이 페이지 파일 (windows) 또는 swap (linux)에 캐시됩니다