Alt-Enter -> Add method stubs * et hop, il ajoute tout ce qui doit être implémenté */ /** * @var ContainerInterface */ private $container; /** * @var ConnectionInterface */ private $clients; /** * ChatHub constructor. * * @param ContainerInterface $_container */ public function __construct(ContainerInterface $_container) { $this->container = $_container; $this->clients = array(); } /** * When a new connection is opened it will be passed to this method * * @param ConnectionInterface $conn The socket/connection that just connected to your application * @throws \Exception */ function onOpen(ConnectionInterface $conn) { echo "Un utilisateur s'est connecté\n"; $response = json_encode([ 'type' => 'msg_server', 'author' => 'server', 'content' => "Bienvenue sur notre Web Socket Server", 'timestamp' => (new \DateTime())->getTimestamp() ]); $conn->send($response); } /** * This is called before or after a socket is closed (depends on how it's closed). SendMessage to $conn will not result in an error if it has already been closed. * * @param ConnectionInterface $conn The socket/connection that is closing/closed * @throws \Exception */ function onClose(ConnectionInterface $conn) { echo "Un utilisateur s'est déconnecté\n"; foreach ($this->clients as $key => $client) { if ($client === $conn) { unset($this->clients[$key]); } } $this->refreshUsers(); } /** * If there is an error with one of the sockets, or somewhere in the application where an Exception is thrown, * the Exception is sent back down the stack, handled by the Server and bubbled back up the application through this method * * @param ConnectionInterface $conn * @param \Exception $e * @throws \Exception */ function onError(ConnectionInterface $conn, \Exception $e) { echo "Une erreur s'est produite\n"; echo $e->getMessage() . "\n"; } /** * Triggered when a client sends data through the socket * * @param \Ratchet\ConnectionInterface $from The socket/connection that sent the message to your application * @param string $msg The message received * @return string * @throws \Twig\Error\Error */ function onMessage(ConnectionInterface $from, $msg) { // retransforme le string $msg en objet $data = json_decode($msg); $dataPath = $data->path; // la route qui nous mène qqpart $dataToken = $data->token; // token d'identification // le token brut, façon JWT $token = new JWTUserToken(); $token->setRawToken($dataToken); switch ($dataPath) { case '/register': // on a créé une fonction private pour partager $username = $this->getUser($token); // from c'est le client qui vient d'envoyer un message // sauvegarde sa 'connection Interface' $this->clients[$username] = $from; $this->refreshUsers(); break; case '/history': // récupère le destinataire $dest = $data->dest; // appelle getUser $username = $this->getUser($token); // récupère l'historique des messages entre les 2 utilisateurs $messageRepo = $this->getDoctrine()->getManager()->getRepository(Message::class); $messages = $messageRepo->getHistory($username, $dest); // passe l'historique dans le fragment twig $twig = $this->container->get('templating'); $fragment = $twig->render('@Socket/Chat/usersHistory.html.twig', array( 'messages' => $messages )); // retourne le fragment en json return json_encode(array( 'action' => 'refreseh_messages', 'view' => $fragment )); break; } } /** * @throws \Twig\Error\Error */ private function refreshUsers() { $em = $this->getDoctrine()->getManager(); $repo = $this->getDoctrine()->getRepository(User::class); // twig va génèrer le fragment à retourner $twig = $this->container->get('templating'); // array_map récupère chaque user et le map avec nos clients $fragment = $twig->render('@Socket/Chat/listUsers.html.twig', array( 'users' => array_map(function ($username) use($repo, $em) { $user = $repo->findOneBy(array('username' => $username)); $em->refresh($user); return $user; }, array_keys($this->clients)) )); // formate la response $response = json_encode(array( 'action' => 'refresh_users', 'view' => $fragment )); // renvoie la réponse à tous les clients foreach ($this->clients as $client) { $client->send($response); } } /** * @return \Doctrine\Bundle\DoctrineBundle\Registry|mixed|object */ private function getDoctrine() { return $this->container->get('doctrine'); } /** * @param $token * @return mixed */ private function getUser($token) { // importe le service qui permet de traiter le token $tokenManager = $this->container->get('lexik_jwt_authentication.jwt_manager'); // payload, ce sont les données chiffrées à l'intérieur du token $payload = $tokenManager->decode($token); // retourne le username qui est dans le payload du token return $username = $payload['username']; } }