Использование сокетов на сайтах uCoz
Как сделать сайт ещё более динамичным? - Этот вопрос часто задают себе разработчики/владельцы/дизайнеры сайтов на uCoz. Конечно, можно поставить дракончика, но есть и другой способ.
Что делать если есть необходимость (или просто желание) оповещать пользователей о каких-либо изменениях на сайте? Динамично (в том числе без лишних действий самого пользователя) изменять содержимое страницы, добавлять новое, уведомлять о чём-либо, не дожидаясь пока пользователь перезагрузит страницу?
Казалось бы, что решение очевидное - создать при загрузке страницы ajax-запрос к скрипту, который будет проверять и искать обновления, и как только он их найдёт - выведет в браузер пользователя. Многие понимают что это большая нагрузка (особенно если посетителей на сайте очень много) и находят решение - не держать постоянный запрос к сайту в поисках обновлений/уведомлений, а просто делать запрос каждый несколько секунд (например раз в пять секунд с помощью setInterval()).
Вроде и всё что касается динамичности страницы без её перезагрузки. Или нет?
Многие из читающих ни разу не слышали, а кто-то слышал, но просто не знает до сих пор что это - о такой вещи как WebSockets. Yandex и Википедия могут немного рассказать об этом - https://ru.wikipedia.org/wiki/WebSocket.
Для тех, кому всё ещё не понятно, сокеты позволяют создать при загрузке страницы сайта соединение с сервером, которое практически не ощутимо в плане нагрузки (в отличии от массивного ajax-запроса, который несомненно создаёт нагрузку на ваш сайт). При создании такого соединения ваш сайт и браузер пользователя "жмут друг другу руки" и остаются в режиме ожидания сообщений.
Всё, что остаётся пользователю, отправить сообщение в сокет и это сообщение моментально (на сколько это возможно) получают все, кто также находится на страницах вашего сайта и подключен к этому же сокету. Учитывая, что подобное соединение может работать одновременно с несколькими тысячами подключений – для разработчика это должно звучать заманчиво, не правда ли?
Как это поможет разработчику?
Например, на странице добавления новости установите скрипт, который после нажатия кнопки "Добавить материал", в случае, если материал успешно добавлен - будет отправлять в сокет данные о новом материале, указав его название и текст - все пользователи находящиеся на страницах сайта, на которых есть скрипт, обрабатывающий входящие сообщения - сразу же увидят новый материал, который вы красиво вставите в нужном месте.
Хотите увидеть как это работает?
Зайдите на тестовую страницу: http://keller.ucoz.com/index/0-2
Откройте эту страницу в нескольких браузерах, после чего в одной из вкладок добавьте новость (укажите тестовое название и текст материала, после чего нажмите "добавить"), в результате - ваша новость сразу будет отображена во всех ваших вкладках, БОЛЕЕ ТОГО, эту новость так же сразу увидят все, кто так же как и вы находитесь на этой странице, ровно как и вы увидите новости, добавленные другими пользователями.
Как начать использовать эту штуку у себя на сайтах?
Для настройки и работы с сокетами вам понадобится свой сервер.
Всё так красиво звучало, а теперь оказалось что нужно ещё и сервер покупать (пусть и не дорогой)?
Безусловно те, кто сможет администрировать сокет-сервер сам - может купить сервер, но для сайтов uCoz есть более удобное решение - сервис предоставляющий доступ к данному протоколу.
Всё, что нужно чтобы начать им пользоваться - это установка JS скрипта на страницы вашего сайта.
1. Создание приложения
Для создания приложения необходимо зарегистрироваться на сервисе, предоставляющем доступ к сокетам.
Заходим на https://talkers.club/, регистрируемся/авторизируемся удобным для вас способом.
После авторизации - переходим во вкладку "Разработчику".
На открывшейся странице нажимаете на кнопку создания приложения и указываете "Название" и "Адрес сайта" (описание можно оставить пустым).
2. Установка на сайт
После создания ваше приложение должно быть одобрено (проверяется в течении суток).
Как только ваше приложение одобрено - можно приступать к работе.
Первым делом вы можете проверить работу вашего приложения установив на все страницы вашего сайта перед закрывающим тегом </body>
вот такой скрипт:
var tio_host = 'talkers.club';
var tio_up = '/php/';
var tio_username = '$USERNAME$';
var tio_server = 8091;
var tio_userid = <?if($USER_LOGGED_IN$)?>$USER_ID$<?else?>0<?endif?>;
var tio_ul = 0;
function showMessage(d){
alert(''+
'd.act - '+d.act+'\n'+
'd.data1 - '+d.data1+'\n'+
'd.data2 - '+d.data2+'\n'+
'd.data3 - '+d.data3+'\n'+
'd.data4 - '+d.data4+'\n'+
'd.data5 - '+d.data5+'\n'+
'd.data6 - '+d.data6+'\n'+
'd.data7 - '+d.data7+'\n'+
'd.data8 - '+d.data8+'\n'+
'd.data9 - '+d.data9+'\n'+
'd.data10 - '+d.data10+'\n'+
'd.data11 - '+d.data11+'\n'+
'd.data12 - '+d.data12+'\n'+
'd.data13 - '+d.data13+'\n'+
'd.data14 - '+d.data14+'\n'+
'd.data15 - '+d.data15+'\n'+
'd.data16 - '+d.data16+'\n'+
'd.data17 - '+d.data17+'\n'+
'd.data18 - '+d.data18+'\n'+
'd.data19 - '+d.data19+'\n'+
'd.data20 - '+d.data20+'\n'+
'');
}
$.getScript('https://'+tio_host+'/js/app_socket.js');
</script>
Где вместо 8091 нужно указать номер сервера, который можно узнать в настройках вашего приложения.
Чтобы проверить правильность установки скрипта установите на любую страницу вот такую ссылку:
После чего откройте страницу со ссылкой в одном браузере, а любую другую страницу сайта (где установлен скрипт для работы с сокетом) в другом браузере.
Нажмите на ссылку и в обоих вкладках появится всплывающее окошко, в котором указаны передаваемые данные (в данном случае в переменной d.data11 будет указано слово "Привет").
Далее всё что вам нужно - используя функцию showMessage(d) и данные, которые она передаёт - писать свой скрипт, который будет обрабатывать все входящие сообщения.
3. Безопасность при работе с сокетами
Всё? Можно начинать использовать?
К сожалению нет. Безусловно то что есть - уже может быть достаточно для реализации некоторых простых идей, но нужно понимать - все ваши JS скрипты доступны в исходном коде страницы, и зная скрипт, обрабатывающий входящие сообщения - можно из браузера ОТПРАВИТЬ поддельное сообщение, тем самым вызвав описанную вами функцию в браузерах всех посетителей сайта.
Логично, что отправку сообщения в сокет нужно как-то закодировать, но как?
Для этого нужно отправить в сокет не сами данные, а ключ, используя который сокет сможет получить эти самые данные и разослать всем пользователям.
Вот так выглядит функция отправки закодированного сообщения:
Где HtusgOUF6d - это ключ, содержащий данные.
4. Получение ключа с данными
Для полноценной работы с протоколом нам нужно подключить PHP в Панели управления сайтом и создать приложение для работы с uAPI.
О покупке PHP можно узнать по этой ссылке - http://forum.ucoz.ru/forum/30-31022-1
О создании приложения для PHP (+ uAPImodule) по этой - http://api.ucoz.net/ru/manual/module
После подключения PHP и создания приложения для работы с uAPI подключаемся к FTP PHP вашего сайта, заходим в папку «scripts» и создаём в ней ещё одну, с названием «talkers», после чего в эту папку загружаем файлы:
«uAPImodule.php» - модуль для работы с uAPI
«tIOuser.php» со следующим содержимым:
$___notjson=1;
$userid = ucoz_getinfo("SITEUSERID");
if(isset($_POST['action'])){
$action = htmlspecialchars($_POST['action']);
if($action=="gethash" AND isset($_POST['user'])){
$login = htmlspecialchars($_POST['user']);
include 'uAPImodule.php';
$option = array(
'oauth_consumer_key' => $consumer_key,
'oauth_nonce' => $oauth_nonce,
'oauth_signature_method' => $sig_method,
'oauth_timestamp' => $timestamp,
'oauth_token' => $oauth_token,
'oauth_version' => $oauth_version,
'user' => $login
);
ksort($option);
$user_data = json_decode(uAPIModule('/users', 'get', $option, ''));
$userid_uapi = $user_data->users[0]->uid;
if($userid_uapi==$userid){
$access = true;
} else {
$access = false;
}
if($access){
$id = "777"; ## ID приложения
$key = "keykeykey"; ## Секретный ключ приложения
$origin = "http://example.ru"; ## Ссылка на сайт
$w_userid = "";
$w_gid = "";
$w_bc = 0;
$data1 = $userid;
$data2 = $user_data->users[0]->group->id;
$data3 = "";
$data4 = "";
$data5 = "";
$data6 = "";
$data7 = "";
$data8 = "";
$data9 = "";
$data10 = "";
$data11 = "";
$data12 = "";
$data13 = "";
$data14 = "";
$data15 = "";
$data16 = "";
$data17 = "";
$data18 = "";
$data19 = "";
$data20 = "";
include 'tIOaction.php';
tio_transfer($id, $key, $origin, $w_userid, $w_gid, $w_bc, $data1, $data2, $data3, $data4, $data5, $data6, $data7, $data8, $data9, $data10, $data11, $data12, $data13, $data14, $data15, $data16, $data17, $data18, $data19, $data20);
} else {echo "{\"code\":\"666\",\"mess\":\"Ошибка доступа!\"}";}
}
}
?>
В коде измените переменные $id, $key и $origin на данные, которые указаны в уже созданном вами приложении.
Будьте аккуратны! Не публикуйте и не сообщайте свой секретный ключ в открытом виде.
«tIOaction.php» со следующим содержимым:
function tio_transfer($id, $key, $origin, $userid, $gid, $bc, $data1, $data2, $data3, $data4, $data5, $data6, $data7, $data8, $data9, $data10, $data11, $data12, $data13, $data14, $data15, $data16, $data17, $data18, $data19, $data20){
$host = "talkers.club";
if($tio = @curl_init()){
@curl_setopt($tio, CURLOPT_URL, 'https://'.$host.'/exe/app/add.php');
@curl_setopt($tio, CURLOPT_RETURNTRANSFER, true);
@curl_setopt($tio, CURLOPT_POST, true);
@curl_setopt($tio, CURLOPT_POSTFIELDS, 'id=' . $id . '&key=' . $key . '&origin=' . $origin . '&userid=' . $userid . '&gid=' . $gid . '&bc=' . $bc . '&data1=' . $data1 . '&data2=' . $data2 . '&data3=' . $data3 . '&data4=' . $data4 . '&data5=' . $data5 . '&data6=' . $data6 . '&data7=' . $data7 . '&data8=' . $data8 . '&data9=' . $data9 . '&data10=' . $data10 . '&data11=' . $data11 . '&data12=' . $data12 . '&data13=' . $data13 . '&data14=' . $data14 . '&data15=' . $data15 . '&data16=' . $data16 . '&data17=' . $data17 . '&data18=' . $data18 . '&data19=' . $data19 . '&data20=' . $data20);
@curl_setopt($tio, CURLOPT_CONNECTTIMEOUT, 30);
@curl_setopt($tio, CURLOPT_SSL_VERIFYPEER, false);
@curl_setopt($tio, CURLOPT_SSL_VERIFYHOST, false);
$data = @curl_exec($tio);
echo $data;
@curl_close($tio);
}
}
?>
Готово!
Теперь, чтобы получить ключ сообщения, нужно при исполнении любого вашего php-скрипта добавить в конце следующий код:
$key = "keykeykey"; ## Секретный ключ приложения
$origin = "http://example.ru"; ## Ссылка на сайт
$w_userid = "";
$w_gid = "";
$w_bc = 0;
$data1 = "";
$data2 = "";
$data3 = "";
$data4 = "";
$data5 = "";
$data6 = "";
$data7 = "";
$data8 = "";
$data9 = "";
$data10 = "";
$data11 = "";
$data12 = "";
$data13 = "";
$data14 = "";
$data15 = "";
$data16 = "";
$data17 = "";
$data18 = "";
$data19 = "";
$data20 = "";
include 'tIOaction.php';
tio_transfer($id, $key, $origin, $w_userid, $w_gid, $w_bc, $data1, $data2, $data3, $data4, $data5, $data6, $data7, $data8, $data9, $data10, $data11, $data12, $data13, $data14, $data15, $data16, $data17, $data18, $data19, $data20);
При этом не забываем указывать данные приложения и в переменных data1 - data20 указывать сами данные, которые хотим передать другим посетителям.
Важно знать! Первые десять переменных передают только числовые данные, т.е. цифры. Десять других - строковые.
Ответом выполнения функции tio_transfer() будет строка в JSON-формате, которая в переменной hash будет содержать нужный нам ключ.
После получения ключа - выполняем функцию sendmess() и все посетители вашего сайта получают сообщение с переданными данными.