<?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();