trinion_base-1.0.x-dev/src/WSServerApplications/WServer.php
src/WSServerApplications/WServer.php
<?php
declare(strict_types=1);
namespace Drupal\trinion_base\WSServerApplication;
use Bloatless\WebSocket\Application\Application;
use Bloatless\WebSocket\Connection;
class WServer extends Application
{
/**
* @var array $clients
*/
private array $clients = [];
/**
* @var array $uids
*/
private array $uids = [];
/**
* @var array $sids
*/
private array $sids = [];
/**
* Handles new connections to the application.
*
* @param Connection $connection
* @return void
*/
public function onConnect(Connection $connection): void
{
$id = $connection->getClientId();
$this->clients[$id] = $connection;
}
/**
* Handles client disconnects.
*
* @param Connection $connection
* @return void
*/
public function onDisconnect(Connection $connection): void
{
$id = $connection->getClientId();
unset($this->clients[$id], $this->uids[$id], $this->sids[$id]);
}
/**
* Handles incomming data/requests.
* If valid action is given the according method will be called.
*
* @param string $data
* @param Connection $client
* @return void
*/
public function onData(string $data, Connection $client): void
{
try {
$decodedData = $this->decodeData($data);
$allowedActions = ['echo', 'setUid'];
if (!in_array($decodedData['action'], $allowedActions)) {
return;
}
$message = $decodedData['data'] ?? '';
if ($message === '') {
return;
}
$clientId = $client->getClientId();
switch ($decodedData['action']) {
case 'echo':
$this->actionEcho($message);
break;
case 'setUid':
$this->uids[$clientId] = $message;
if (isset($message['uid']))
$this->sids[$clientId] = $message['uid'] ? $message['uid'] : $message['sid'];
else
$this->sids[$clientId] = $message;
break;
}
} catch (\RuntimeException $e) {
// @todo Handle/Log error
}
}
/**
* Handles data pushed into the websocket server using the push-client.
*
* @param array $data
*/
public function onIPCData(array $data): void
{
$actionName = 'action' . ucfirst($data['action']);
// $message = 'System Message: ' . $data['data'] ?? '';
if (method_exists($this, $actionName)) {
call_user_func([$this, $actionName], $data['data']);
}
}
/**
* Echoes data back to client(s).
*
* @param string $text
* @return void
*/
public function actionEcho(string $text): void
{
$encodedData = $this->encodeData('echo', $text);
/** @var Connection $sendto */
foreach ($this->clients as $sendto) {
$sendto->send($encodedData);
}
echo "ping \n";
}
/**
* Message to the client.
*
* @param string $encodedData
* @param string $clientId
* @return void
*/
public function actionSend(string $encodedData, string $clientId): void
{
/** @var Connection $sendto */
foreach ($this->clients as $sendto) {
if ($sendto->getClientId() == $clientId) {
$sendto->send($encodedData);
echo "send {$encodedData} to {$clientId}\n";
}
}
}
public function actionNewCallPopup($data) {
foreach ($this->uids as $clientId => $uid) {
if ($data['uid'] == $uid) {
$encodedData = $this->encodeData('newCallPopup', $data);
$this->clients[$clientId]->send($encodedData);
}
}
}
public function actionNewPickupPopup($data) {
foreach ($this->uids as $clientId => $uid) {
if ($data['uid'] == $uid) {
$encodedData = $this->encodeData('newPickupPopup', $data);
$this->clients[$clientId]->send($encodedData);
}
}
}
public function actionCallFinish($data) {
foreach ($this->uids as $clientId => $uid) {
if ($data['uid'] == $uid) {
$encodedData = $this->encodeData('callFinish', $data);
$this->clients[$clientId]->send($encodedData);
}
}
}
public function actionNewChatMessage($data) {
foreach ($this->sids as $clientId => $sid) {
if ($data['sid'] == $sid && isset($this->clients[$clientId])) {
$encodedData = $this->encodeData('newChatMessage', $data);
$this->clients[$clientId]->send($encodedData);
}
}
}
}
