nineschool/src/nineschool-1.0/src/Websocket/MessageHandler.php

114 lines
3.6 KiB
PHP

<?php
namespace App\Websocket;
use Exception;
use Ratchet\ConnectionInterface;
use Ratchet\MessageComponentInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\EntityManagerInterface;
use SplObjectStorage;
class MessageHandler implements MessageComponentInterface
{
protected $container;
protected $em;
protected $clients;
private $subscriptions;
private $users;
public function __construct(ContainerInterface $container, EntityManagerInterface $em)
{
$this->container = $container;
$this->em = $em;
$this->clients = new SplObjectStorage;
$this->subscriptions = [];
$this->users = [];
$this->keys = [];
}
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
$this->users[$conn->resourceId] = $conn;
}
public function onClose(ConnectionInterface $conn)
{
$data= new \stdClass;
$data->command = "adead";
$this->sendMessage($conn,$data,false);
$this->clients->detach($conn);
unset($this->users[$conn->resourceId]);
unset($this->keys[$conn->resourceId]);
unset($this->subscriptions[$conn->resourceId]);
}
public function onError(ConnectionInterface $conn, Exception $e)
{
$conn->close();
}
public function onMessage(ConnectionInterface $conn, $msg)
{
$data = json_decode($msg);
switch ($data->command) {
case "subscribe":
$this->subscriptions[$conn->resourceId] = $data->channel;
$this->keys[$conn->resourceId] = $data->key;
break;
case "meto":
if (isset($this->subscriptions[$conn->resourceId])) {
$this->sendMessage($conn,$data,false);
}
break;
case "alive":
default:
if (isset($this->subscriptions[$conn->resourceId])) {
$this->sendMessage($conn,$data);
}
break;
}
}
private function sendMessage(ConnectionInterface $conn, $data, $tome=true) {
$target = $this->subscriptions[$conn->resourceId];
foreach ($this->subscriptions as $id=>$channel) {
if ($channel == $target) {
if($tome||(!$tome&&$id!=$conn->resourceId)) {
// From
$key= $this->keys[$conn->resourceId];
$from=$this->em->getRepository("App:User")->findOneBy(["apikey"=>$key]);
// To
$key= $this->keys[$id];
$to=$this->em->getRepository("App:User")->findOneBy(["apikey"=>$key]);
// Send
if($from && $to) {
$data->from= new \stdClass;
$data->from->id = $from->getId();
$data->from->username = $from->getUsername();
$data->from->displayname = $from->getDisplayname();
$data->from->avatar = $this->getAvatar($from->getAvatar());
$data->log="== GET MSG from ".$data->from->username." to ".$to->getUsername()." = ".$data->command;
$this->users[$id]->send(json_encode($data));
}
}
}
}
}
private function getAvatar($avatar) {
if(stripos($avatar,"http")===0)
return $avatar;
else
return "/".$this->container->getParameter("appAlias")."/uploads/avatar/".$avatar;
}
}