Рубрики
Uncategorized

Использование websocket в PHP-сервисах

Автор оригинала: David Wong.

WebSocket

Протокол Websocket родился в 2008 году и стал международным стандартом в 2011 году. Все браузеры уже поддерживаются.

Его самая большая особенность заключается в том, что сервер может активно передавать информацию клиенту, а клиент также может активно отправлять информацию на сервер. Это настоящий двусторонний равноправный диалог, который относится к технологии push сервера.

Почему websocket?

Требование заключается в следующем: если пользователь остается на странице в течение 15 минут без каких-либо операций, появится окно входа, позволяющее пользователю снова войти в систему.

Как правило, опрос длинных соединений является наиболее распространенным требованием, которое связано с такими проблемами, как зависание браузера, потребление сервера и сложность обслуживания.

Позже мы обнаружили, что websocket обладает следующими преимуществами:

  • На основе протокола TCP реализация сервера проста.
  • Его нелегко защитить, когда он находится под рукой, и он может проходить через различные прокси-серверы HTTP.
  • Формат данных легкий, затраты на производительность невелики, а эффективность связи высока.
  • Вы можете отправлять текстовые или двоичные данные.
  • Нет никаких ограничений на гомологию. Клиент может взаимодействовать с любым сервером.
  • Идентификатор протокола-WS (WSS, если зашифрован), а URL-адрес сервера-это URL-адрес.

Цель выбрана, так как же ее достичь?

В PHP уже есть очень простая в использовании асинхронная сетевая коммуникационная платформа swool , которая экономит время на реализации сервиса websocket. Я использовал фреймворк laravel и, наконец, выбрал расширение laravel swool.

Конфигурация установки

Представлен вики-пакет расширения laravel swool. Включите websocket.включено И другие соответствующие конфигурации, следующие имена могут облегчить управление службами:

php artisan swoole:http {start|stop|restart|reload|infos}

Измените значение по умолчанию в профиле обработчике Классе, настроенном как настройка: в основном для настройки websocket Некоторые обратные вызовы в жизненном цикле.

    /*
    |--------------------------------------------------------------------------
    | Websocket handler for onOpen and onClose callback
    | Replace this handler if you want to customize your websocket handler
    |--------------------------------------------------------------------------
    */
    'handler' => \App\Listeners\Swoole\WebsocketHandler::class,

    /*
    |--------------------------------------------------------------------------
    | Default frame parser
    | Replace it if you want to customize your websocket payload
    |--------------------------------------------------------------------------
    */
    'parser' => SwooleTW\Http\Websocket\SocketIO\SocketIOParser::class,

Когда конфигурация завершена, маршруты Добавляют каталог с именем websocket.php Документы. Очень удобно определять все виды событий так же, как маршрут laravel. Например:

//Websocket::on('open', function ($websocket, Request $request) {
//    Log::info('websocket','open 111 +' . $websocket->getSender());
//});
//
//Websocket::on('connect', function ($websocket, Request $request) {
//    Log::info('websocket','Connected ++ 222' . $websocket->getSender());
//    // called while socket on connect.
//});
//
//Websocket::on('disconnect', function ($websocket) {
//    Log::info('websocket','Disconnected ++ 333' . $websocket->getSender());
//    // called while socket on disconnect
//});

//In the checklogin method of usercontroller, there will be two parameters, $websocket and $data.
Websocket::on('loginCheck', "App\Http\Controllers\Api\[email protected]");

Websocket::on('logout', "App\Http\Controllers\Api\[email protected]");

Воспользуйся

Контроллер:

public function checkLogin($websocket, $data)
{
    if (empty($data['holding'])) {
        $websocket - > Exit ('message ', ['code' = > self:: http  unprocessable  entity, 'message' = > parameter error ');

        return false;
    }
    $flag = true;
    $step = 1;
    while ($flag) {
        $step++;
        if ( ! $this->validateLoginStatus($data['holding'])) {
            $websocket - > Exit ('message ', ['code' = > self:: http_unauthorized, 'message' = > login timeout ');
            unset($step);
            $flag = false;
        }else {
            if($step === 1) {
                $websocket->emit('message', ['code' => self::HTTP_OK, 'message' => "success"]);
            }
        }
        sleep(1);
    }
}

Входящий вызов

Обратите внимание на структуру пакета данных здесь. Пройдя через множество ям, документы API могут найти правильную структуру:

var websocket = new WebSocket("ws://127.0.0.1:1215");
    websocket.onopen = function (evt) {
        Console.log ("websocket server connected");
        //Here is the key point. After the channel is established, it is very convenient to poll
        setInterval(function() {
           if (websocket.bufferedAmount == 0)
              var data = {"holding": "eyJLQNDqj0y473pCJ6zjMTUyOTk5NzU1MgnVMQ==$d84XkeMCv7umajhMRiU"};
              websocket.send(encodeMessage('loginCheck', data));
        }, 50);
    };
    //Monitor message body
    websocket.onmessage = function (evt) {
        console.log(decodeMessage(evt.data))
    };
    //Listen for close messages
    websocket.onclose = function (evt) {
        console.log("websocket close");
    };
    //Listen for connection error messages
    websocket.onerror = function (evt) {
        console.log(evt);
    };

    function decodeMessage(str) {
        return JSON.parse(str.substring(2))[1] || [];
    }

    function encodeMessage(event, data) {
        return JSON.stringify([
            event,
            data
        ])
    }

Установка расширения Swool

Потому что установка swoole зависит от php | сокетов Открытия модуля.

  • Установите swool

Для промежуточного сообщения об ошибках необходимо установить следующие зависимости:

yum -y install gcc postgresql-devel gcc-c++

Загрузите весь исходный код расширения и выполните шаги по установке.

Мониторинг производительности

Просмотр текущего

$ netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

TIME_WAIT 814
CLOSE_WAIT 1
FIN_WAIT1 1
ESTABLISHED 634
SYN_RECV 2
LAST_ACK 1

Три обычно используемых состояния: УСТАНОВЛЕНО Указывает, что связь продолжается, TIME_WAIT Указывает на активное завершение работы, CLOSE_WAIT Указывает на пассивное выключение.

Процесс удаления

Просмотр количества процессов

$ ps -eaf |grep "swoole" | grep -v "grep"| awk '{print $2}'|wc -l

Процесс массового удаления:

$ ps -eaf |grep "swoole" | grep -v "grep"| awk '{print $2}'|xargs kill -9

Перезапустите службу.

Справочные статьи

Учебник по веб-карману Руан Ифэн