Lekce 3 - Návštěvní kniha přes WebSocket - Zprovoznění komunikace
V minulé lekci, Návštěvní kniha přes WebSocket - Server a hlavní PHP třída, jsme implementovali jednoduchý Node.js server a začali s PHP serverem, kde jsme vytvořili hlavní třídu a autoloader.
Dnes vytvoříme třídu pro volání Node.js serveru a přidáme si slíbenou šablonu.
PHP/classes/WebSocketApi.php
Tato třída slouží pro volání Node.js serveru a získání odpovědi, zda se přeposlání požadavku přes WebSockets na další klienty povedlo. Bude obsahovat jednu metodu a to "sendSocket()" s parametry "$channel", "$data" a tři privátní proměnné:
- "$password" - stejné heslo jako v souboru "server.js"
- "$ip" - localhost
- "$port" - 4000
Ukažme si kód třídy, jako vždy si ho hned popíšeme:
<?php class WebSocketApi { private $password = "d$0awd6$5ZVawdIhlawdZJr8xwadtRFnSlbRX2.$2a$0awd6$5ZVIhawdlZJwdr8xtRFnS72lbRX2.Dsylt5.YSi1BzzqawdBt3rsBawdxYQMYIqsFe", $ip = "localhost", $port = 4000; public function sendSocket($channel, $data) { $Url = "http://$this->ip:$this->port"; $ch = curl_init(); $POST = ["channel" => $channel, "password" => $this->password, "data" => json_encode($data, JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_QUOT)]; $POST_string = null; foreach ($POST as $key => $value) { $POST_string .= $key.'='.$value.'&'; } rtrim($POST_string, '&'); curl_setopt($ch, CURLOPT_URL, $Url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch,CURLOPT_POST, count($POST)); curl_setopt($ch, CURLOPT_POSTFIELDS, $POST_string); $response = curl_exec($ch); curl_close($ch); return $response == "true"; } }
Metoda "sendSocket()" obsahuje proměnnou "$Url", která sjednotí IP adresu a port do jednoho. Dále načítáme curl (technologie pro posílání webových požadavků z PHP, na některých webhostinzích ji je třeba aktivovat) a vytváříme pole s nastavením pro curl. Kousek níže vytváříme pole s POST daty. Cyklus přemění POST data na string, funkcí rtrim() na konci odstraníme poslední "&". Nyní již jen trochu nastavíme curl a do proměnné si uložíme výsledek požadavku na Node.js server. Následně zavřeme curl a vrátíme true pokud jsme od serveru dostali řetězec "true", v opačném případě vrátíme false jako neúspěch.
Abychom mohli náš PHP server vyzkoušet, potřebujeme ještě chybějící šablonu. Pojďme si ji přidat.
PHP/template.phtml
Obsah souboru bude zatím pouhá html kostra s jQuery, socket.io, Font Awesome a vlastním stylem, který také vytvoříme. Soubor bude vypadat nějak takto:
<!DOCTYPE html> <html> <head lang="cs-cz"> <meta charset="UTF-8"> <meta name="author" content="Patrik Smělý(SogoCZE)"> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="description" content="Realtime Kniha návštěv"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Realtime Kniha návštěv</title> <base href="localhost"> <link rel="stylesheet" type="text/css" href="/css/style.css"> <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" charset="UTF-8"></script> <script src="https://cdn.socket.io/socket.io-1.2.0.js" charset="UTF-8"></script> </head> <body> <h1>Realtime Kniha návštěv</h1> </body> </html>
PHP/CSS/style.css
K šabloně potřebujeme i nějaké ty styly. Vytvoříme tedy adresář "css" v našem PHP adresáři a v něm ještě soubor "style.css". Ten bude zatím obsahovat jen pár základních věcí a to:
* { padding: 0 0 0 0; margin: 0 0 0 0; box-sizing: border-box; } body { background-color: #DDDDDD; color: black; font-size: 14px; font-family: Helvetica Neue, Helvetica, Arial; }
Jdeme tedy konečně vyzkoušet náš PHP systém a celé websocket API! Do metody "mainMethod()" ve třídě "MainClass" přidáme následující kód:
PHP/classes/MainClass.php
public function mainMethod() { $WebSocketApi = new WebSocketApi(); if ($WebSocketApi->sendSocket("Test", ["name" => "Patrik", "message" => "testing"]) === true) { echo("Povedlo se! Nodejs vrací true!"); } else { echo("Něco se nepovedlo! Node.js nevrací true!"); } echo $this->render(); }
Vytvoříme instanci našeho websocketového API a přidáme podmínku, ve
které budeme volat metodu "sendSocket()". Parametry jsou Kanál a [data]. Jako
kanál zvolíme např. řetězec "Test" a do dat dáme například
["name" => "Patrik", "message" => "testing"]
.
Vraťme se zpět k naší podmínce. Pokud tato metoda vrátí true, vypíšeme "Povedlo se! Node.js vrací true!“ Když tomu tak není, vypíšeme "Něco se nepovedlo! Node.js nevrací true!".
Nyní spustíme Apache v XAMPPu a přes prohlížeč přejdeme na adresu "localhost". Měli bychom dostat následující výsledek:

Hm, to nám toho ale moc neřeklo že? Zkusme si tedy trochu toho real-timu. Přejdeme do template.phtml a pod <h1> nadpis si vložíme div s třídou "messages". Pod něj vložíme script, který bude došlé zprávy v reálném čase přidávat do stránky.
PHP/template.phtml
<div class="messages"></div> <script type="application/javascript"> var Sockets = io.connect('localhost:4000'); Sockets.on('Test', function(data) { $('.messages').append("<span>" + data.name + ": " + data.message + "</span><br/>"); }); </script>
Pomocí metody io.connect() se připojíme k serveru a budeme naslouchat na daném kanálu. Parametrem metody connect() je IP adresa a port. Tímto připojíme uživatele k našemu serveru. Jako callback má naslouchací metoda on() nastavenou funkci, která v parametrech přijímá data. Tu využijeme pro výpis dat z PHP serveru. V callback funci připojíme do našeho divu spany s proměnnými data.name a data.message. Tím do stránky přidáme došlé zprávy. Měli byste dostat následující výsledek:

Když si nyní web načteme 2x vedle sebe a jeden obnovíme, na druhém se
okamžitě ukáže naše zpráva. To znamená, že PHPčko odeslalo data do
Node.js a ten obeslal uživatele a vynutil obnovení stránky. Komunikujeme tedy
z PHP s klienty, aniž by zavolali PHP požadavek. No není to úžasné? Naše API funguje jak má.
V příští lekci, Návštěvní kniha přes WebSocket - Šablona aplikace, dodáme aplikaci hezčí kabát.