Керований комп'ютером через браузер

Комп'ютер давно багатьом замінив телевізор, а що не вистачає комп'ютера для комфортного перегляду кіно, серіалів і іншого? Мені особисто не вистачало пульта дистанційного керування.

image
Я не багато захоплююсь веб-програмуванням у вільний час. Було вирішено написати свій велосипед і заодно поєднати приємне з корисним. Була вивчена можливість за допомогою консолі управляти комп'ютером, в першу чергу мене цікавило наступний мінімальний обсяг завдань (який трохи збільшився в наслідку):

  • Можливість відправити ПК в режим сну
  • Можливість вимкнути гучність
З допомогою відомого пошуковика знайшов консольну програму, NirCmd, програма дозволяє здійснювати досить багато дій, крім зазначених вище. З основною частиною ми визначилися. Як я говорив, не багато вивчаю php, веб-сервер в мене як правило запущений постійно, тому нічого специфічного в плані сервера я придумувати не став. Сервер написаний на php і складається з двох класів: Control, який представляє собою методи, які виконують консольні команди Route, який робить валідацію приходять запитів і виконує методи класу Control.

Control виглядає ось так (код однотипний, тому я скоротив):

class Control implements ActionControl {
protected $Path; //шлях до програми nirCmd;

function __construct($p = 'C:/nircmd/nircmd.exe') {
$this->Path = $p;
}
function standby() {
`{$this->Path} standby`;
}
function hibernate() {
`rundll32 powrprof.dll,SetSuspendState 0,1,0`;
}
function reboot() {
`{$this->Path} exitwin reboot`;
}
function повороту() {
`{$this->Path} exitwin poweroff`;
}
function logout) {
`{$this->Path} exitwin logoff`;
}
}

Другий клас, — Route. Власне до нього звертається клієнт. Клас, в першу чергу здійснює валідацію запиту, якщо запит правильний викликає методи класу Control.
Виглядає це так:

class Route implements ActionRoute {
protected $possible = []; 
protected $ControlObj;

function __construct($obj) {
$this->possible = get_class_methods($obj); 
$this->ControlObj = $obj;
}
function route($arr) { 
forEach($arr as $key = > $value) { 
if (in_array($key, $this->possible) && $value == 'true') {
$this- > execute($key);
} else 
{
Message::sent('wrong method');
} 
}
}
function execute($c) {
$this->ControlObj->$c();
Message::sent('executed');
}
}

Щоб вийшло в разі чого легко розширити кількість методів у класі Control, валідація в класі Route жорстко не прив'язана до певного списку методів класу Control, точніше прив'язана, але всі можливі методи витягуються з самого об'єкта, з ними і йде порівняння прийшли даних.

Сам файл до якого звертається клієнт виглядає ось так:

<?
define("PATH", "C:/nircmd/nircmd.exe"); 
function __autoload($name) {
require "class/$name.class.php";
}

$obj = new Control(PATH);
$route = new Route($obj);

if ($_GET) {
$route->route($_GET);
}
?>

Якщо приходить GET запит, то весь масив віддаємо методом route.

Клієнтська частина являє собою кнопки управління і один обробник, за яким ми шолом дані за допомогою ajax на сервер.

var wrapper = document.querySelector(".wrapper");

function getXmlHttpRequest(){
if (window.XMLHttpRequest) {
try {
return new XMLHttpRequest();
} catch (e){ }
} else if (window.ActiveXObject) {
try {
return new ActiveXObject('Msxml2.XMLHTTP');
} catch (e){}
try {
return new ActiveXObject('Microsoft.XMLHTTP');
} catch (e){}
}
return null;
}

wrapper.addEventListener. ('click', function(e){
var target = e.target;

if(target.tagName!= 'BUTTON') return;
if (target.getAttribute('data')=='qestion') {
var yn = confirm("Впевнений?");
if (!yn) return
ajaxf(target.id);
}
ajaxf(target.id);
})

function ajaxf($com) {
var command = $com+'=true';
var xhr = new getXmlHttpRequest();
xhr.open('GET', 'remote.php?'+command, true);
xhr.send();
xhr.onreadystatechange = function() { 
if (xhr.readyState != 4) return;
if (xhr.status != 200) {
console.log(xhr.status + ': '+ xhr.statusText);
} else {
console.log(xhr.responseText);
}
}
}

На сьогодні реалізовано наступний функціонал управління:

  • сплячий режим
  • гібернація
  • перезавантажиться
  • вимкнути
  • вийти
  • вимкнути монітор
  • увімкнути/вимкнути звук у відповідь на дію
  • гучність більше
  • гучність менше
  • Медіа кнопки stop/play next/prev
Все, що я хотів отримати, отримав, але, як говориться, апетит приходить під час їжі. Хотілося б мати зворотний зв'язок від сервера, тобто при першому заході на сторінку робити запит поточного рівня гучності наприклад. На жаль, nirCmd не повертає значення при виконанні, тому з тим, що маємо зараз, я не знаю, як це здійснити.

Питання безпеки. Хоча це все і крутиться на локальній машині, буде дуже сумно, якщо доступ до виконання команд nirCmd буде у зловмисника, оскільки можна створити багато деструктивних дій.

Готовий проект на GIthab.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.