Предыстория:
не так давно я столкнулся с проблемой многопоточных запросов при написании системы сообщений для своего проекта. Суть проблемы в том, что нужно было всего лишь посчитать количество Входящих и Исходящих сообщений одного конкретного пользователя. Пользуюсь я, к слову говоря, плагином MySQL R7 от BueG. Так вот, все в принципе решаемо, однако, для каждого запроса приходилось бы создавать свой, отдельный Public -> именно так разработчик решил проблему многопоточности... Вроде бы все нормально, два запроса == два паблика, ничего плохого, вот только... Вот только то, что с каждым, грубо говоря, новым запросом потребуется и новый Public... Это просто загрязнение кода...
Решение проблемы:
на самом деле я нашел в интернете кучу всего полезного, однако, никак не подходившего под мои нужды. Спустя некоторое время после начала поиска, пришлось остановиться на такой замечательной функции, как HTTP();.
Немного введения в курс дела:
Функция доступна с версии 0.3b и с помощью её мы можно отправлять HTTP запрос и получать ответ.
Параметры функции:
PHP код:
(index, type, url[], data[], callback[])
index - ID (playerid, giveplayerid)
type - тип запроса который вы хотите отправить
url[] - URL запроса (без "http://")
data[] - любое сообщение данных которое будет отправлено с запросом
callback[] - Название функции обратного вызова если вы хотите использовать для обработки ответов на этот запрос.
Типы запросов(type):
PHP код:
HTTP_GET - Отправляет запрос на http.
HTTP_POST - Отправляет запрос с данными.
HTTP_HEAD - Отправляет запрос HTTP, но игнорирует любые данные ответа - возвращение только код ответа.
Коды ответов:
PHP код:
HTTP_ERROR_BAD_HOST 1
HTTP_ERROR_NO_SOCKET 2
HTTP_ERROR_CANT_CONNECT 3
HTTP_ERROR_CANT_WRITE 4
HTTP_ERROR_CONTENT_TOO_BIG 5
HTTP_ERROR_MALFORMED_RESPONSE 6
А так же стандартные коды ответов:
PHP код:
HTTP 404 (страница не найдена), 500 (ошибка сервера) или 403 (запрещено)
Более глубоко в описание и приведение примеров работы функции я вдаваться не буду. Кому нужно -> в интернете достаточно информации для персонального штудирования.
Теперь перейдем к тому, как же я применил эту функцию на практике и в своем решении:
В моем случае HTTP взаимодействует с PHP файлом на сервере, отправляя ему определенный запрос и получая зашифрованный ( если это потребуется ) ответ, который позже расшифровывается и далее уже используется по необходимости.
Пример:
PHP код:
/* В самый верх "мода" */
#define PHP_FILE_LOCATION "адрес/Название.php" // Web-адрес ( путь ) до вашего PHP файла ( без http:// )
#define SECURITY_CODE "12345" // Ключ безопасности. Используется для предотвращения несанкционированного доступа к php файлу
#include <a_php>
это рабочий код, в котором я хочу получить количество Принятых/Отправленных сообщений определенным пользователем.
PHP код:
new parameters[24], switch_case[24] = "inputAndOutputMessages";
format(parameters, sizeof(parameters), "%s", getName(playerid));
RunMySQLQuerySwitch(100, switch_case, parameters); // Отправляем запрос
PHP файл:
PHP код:
define('SECURITY_CODE', 'Тут ключ безопасности, который должен совпадать с ключом из кода Pawn');
if($_POST[security] == SECURITY_CODE)
{
$caseQuery = mysql_real_escape_string($_POST[switch_case]);
if(!empty($caseQuery))
{
switch($_POST[switch_case])
{
case "inputAndOutputMessages":
// Тут то, что мы хотим сделать.
die;
break;
}
} else {
echo 'Error.';
}
} else {
echo('Wrong Security Code');
}
Сам [INC] a_php.inc
PHP код:
/*
PHP Library Fallen A. ( AlexandeR )
ver. 0.1a
*/
#include <a_http>
#define MAX_PHP_LENGTH 256
forward OnServerTryingToRunPHP(index, response_code, data[]);
forward OnScriptResponse(scriptid, contents[]);
stock RunMySQLQuerySwitch(scriptid, const switch_case[], const parameters[])
{
new string[MAX_PHP_LENGTH+5];
format(string, sizeof(string), "switch_case=%s¶meters=%s&security="SECURITY_CODE, switch_case, parameters);
HTTP(scriptid, HTTP_POST, PHP_FILE_LOCATION, string, "OnServerTryingToRunPHP");
}
public OnServerTryingToRunPHP(index, response_code, data[])
{
if(response_code != 200)
{
printf("Error: %d, trying to compile PHP on external server.", response_code);
return 0;
}
CallLocalFunction("OnScriptResponse", "ds", index, data); // Возвращаем ответ в Pawn код
return 1;
}
Обработка ответа сервером:
PHP код:
public OnScriptResponse(scriptid, contents[])
{
if(scriptid == 100) // Указываем, что нужно делать с запросом определенного ID
// Тут действие
// При желании можно обрабатывать запросы, полученные с кодирование [B]base64[/B]
return 1;
}
Я не знаю, насколько это работает быстрее плагина, однако, позволяет использовать некоторые возможности и преимущества PHP.
Единственное, что пока достоверно известно -> скорость получения информации напрямую зависит от скорости отправки, обработки и обратного возвращения запроса.