В данной статья расскажу мой опыт работы с websockets в PHP. Сравним 2 пакеты который на мой взгляд являются лучшими.
Уже несколько дней как пробую создать сервер работающий в PHP а в частности в фреймворке Yii2.
Почему сокеты?
Решил использовать сокеты потому что данная технология очень быстро работает. Например API Телеграмма работает с сокетами, у них есть всего-лишь несколько функций которые работают как обычный API.
Мне на Yii2 нужно писать тоже API сервис.
Какие пакеты пробовал использовать?
- cboden/ratchet: “^0.4.0” – этот работает но не адаптирован под Yii2
- workerman/phpsocket.io: “^1.1” – этот не понравился, поэтому даже не буду про него писать
- yiicod/yii2-socketio: “^1.1” – не работает но по идее адаптирован
Работа с пакетом yiicod/yii2-socketio
Установил пакет через composer и настроил в файле config/console.php добавил такие конфигураций:
$config = [
/* ... */
'components' => [
/* ... */
'broadcastEvents' => [
'class' => \yiicod\socketio\EventManager::class,
'nsp' => 'unikalinyy cluchi',
'namespaces' => [
'app\socketio',
]
],
'broadcastDriver' => [
'class' => \yiicod\socketio\drivers\RedisDriver::class,
'hostname' => 'localhost',
'port' => 6379,
],
],
/* ... */
'controllerMap' => [
'socketio' => [
'class' => \yiicod\socketio\commands\SocketIoCommand::class,
'server' => 'localhost:6379'
],
]
/* ... */
]; Потому что функция pcntl_fork не запускалась на сервера установленые на Windows (в моём случае это OpenServer + Windows 10) то пришлось взять в аренду выделеный сервер. Хотел купить от McHost потому что доволен ихними услугами, но у них слабые сервера не продаются (для тестов) поэтому взял за 150 руб в месяц сервер от компаний FirstVDS. Пришлось установить Redis и настроить прослушку портов.
После долгих попыток всё-же получилось и сервер включился.
Но после этого появилась новая проблема: когда клиент (браузер) отправлял запрос на подключение, ему отказывали в рукопожатие (handshake), поэтому пришлось пробовать другие пакеты.
Работа с пакетом cboden/ratchet
Установил себе данный пакет и вот что написал:
config/console.php
/*...*/
$config['bootstrap'][] = 'ratchet';
$config['modules']['ratchet'] = [
'class' => 'app\controllers\AppController',
];
return $config; servers/AppServer.php
<?php
namespace app\servers;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class AppServer implements MessageComponentInterface
{
protected $clients;
public function __construct()
{
$this->clients = new \SplObjectStorage; // Для хранения технической информации об присоединившихся клиентах используется технология SplObjectStorage, встроенная в PHP
}
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
echo "New connection! ({$conn->resourceId})\n";
}
public function onMessage(ConnectionInterface $from, $msg)
{
echo $msg."\n";
$from->send(strtoupper($msg));
}
public function onClose(ConnectionInterface $conn)
{
$this->clients->detach($conn);
echo "Connection {$conn->resourceId} has disconnected\n";
}
public function onError(ConnectionInterface $conn, \Exception $e)
{
echo "An error has occurred: {$e->getMessage()}\n";
$conn->close();
}
} controllers/AppController.php
<?php
namespace app\controllers;
use app\servers\AppServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use Ratchet\Server\IoServer;
use yii\web\Controller;
class AppController extends Controller
{
public $io_port = 6380;
/**
* Start a Web Soket server
* @return null
*/
function setInstance() {
$server = IoServer::factory(
new HttpServer(
new WsServer(
new AppServer()
)
),
$this->io_port
);
$server->run();
}
} Всё, это весь код и он работает. Работал и на локальной машине и работает и на VDS:
Заключение
Если есть рекомендаций можете оставить их в комментарии.
Данную статью писал пока ждал ответа от поддержки FirstVDS, не то чтоб они прямо очень трудно отвечают. Но ждать приходилось и больше получаса иногда, зато помогли – спасибо им.
Очень разочаровался в работе серверов FirstVDS.
Сайты неделю работали медленно очень, а потом день вообще не работали.
Вернулся в McHost.