Задать вопрос
kotcich
@kotcich
Я скучный.

Есть ли на Yii2 нормальные websocket'ы?

Consik, документация которого, даже не дает пример того, как закрыть этот самый сокет(ctrl+c то все сделает, вот только в этом случаи не сработает триггер на закрытие соединения), а в случаи если самому порыться в коде, то оказывается что любая попытка обращения к серверу вне команды actionStart оказывается просто в консоль ритернет xxxxxx, потому что свойства не публичные, а при изменении их на публичные, почему то результат тем же остается.

Так же вообще нет методов для возможности как прочекать клиента на моменте при попытке к подключению, но перед самим подключением. Ну то есть это грубо говоря простейшая реализация для чатика, а при любой попытке получить результат не описанный в примерах документации, у вас просто не с работает.
Остальные на китайском и есть вроде как 1 нормальный по прмиерам и тд и тп, но он просто не устанавливается, так как видимо был разработан под Yii1.

Что юзать то?)
  • Вопрос задан
  • 381 просмотр
Подписаться 1 Простой Комментировать
Решения вопроса 1
cr1gger
@cr1gger
Все дороги ведут в Рим — встретимся в Риме!
Зачем именно под yii ищешь. Бери шире)
https://github.com/walkor/Workerman

Сам пользуюсь ею на Yii2 и нормально все

Можешь на мой ГК посмотреть :D
Но лучше его конечно переписать на адекватный код, потому что это я писал чтобы написать, работает и ладно
chat на вебсокетах

<?php

use Workerman\Worker;
require_once __DIR__ . '/vendor/autoload.php';

$unique_users = [];
$context = array(
    'ssl' => array(
        'local_cert'  => __DIR__ . '/privatessl/cert.pem',
        'local_pk'    => __DIR__ . '/privatessl/key.key',
        'verify_peer' => false,
    )
);

// Create a Websocket server with ssl context.
$ws_worker = new Worker('websocket://website.ru:6374', $context);

$ws_worker->transport = 'ssl';

$ws_worker->onMessage = function ($connection, $data) use ($ws_worker, &$unique_users) {
    $response = json_decode($data);
    ## Команды ##
    if (isset($response->command)) {

        ## Получение пользователей онлайн ##
        if ($response->command == 'getOnline') {

            $connection->send(getOnline($unique_users));
        }
        ## Отправка нового сообщения ##
        if ($response->command == 'sendMessage' && isset($response->message) && !empty($response->message)) {
            sendMessage(
                $response->message,
                $response->login,
                $response->avatar,
                $ws_worker,
                $connection
        );
        }
    }
};
$ws_worker->onConnect = function($connection) use (&$unique_users)
{
    $ip = $connection->getRemoteIp();
    if (!in_array($ip, $unique_users))
    {
        $unique_users[] = $ip;
    }
};
$ws_worker->onClose = function($connection) use (&$unique_users)
{
    $ip = $connection->getRemoteIp();
    $index = array_search($ip, $unique_users);
    unset($unique_users[$index]);
};
function getOnline($unique_users)
{
    $online = [
        'action' => 'online',
        'body' => count($unique_users),
    ];
    return json_encode($online);
}
function sendMessage($message,$login, $avatar, $worker, $connection)
{
    $body = [
        'action' => 'newMessage',
        'body' => $message,
        'login' => $login,
        'avatar' => $avatar,
        'time' => date('d.m.Y в H:i', (time() + 10800))
    ];
    foreach ($worker->connections as $client) {
        $client->send(json_encode($body));
    }
    addMessageDB($message, $login, $avatar);
}
function prepareText($text)
{
    return htmlspecialchars($text);
}
function addMessageDB($message, $login, $avatar){
    $db_config = require(__DIR__ . '/config/db.php');
    $db = new PDO($db_config['dsn'] . ';charset=' . $db_config['charset'], $db_config['username'], $db_config['password']);
    $sth = $db->prepare('INSERT INTO chat_message (message, created_at, login, avatar) VALUES (:mess, :create_time, :login, :avatar)');
    $sth->execute([
        ':mess' => prepareText($message),
        ':create_time' => time(),
        ':login' => prepareText($login),
        ':avatar' => prepareText($avatar),
    ]);
    return $sth->fetchAll(PDO::FETCH_ASSOC);
}
Worker::runAll();

Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы