Válí se ti projekty v šuplíku? Dostaň je mezi lidi a získej cool tričko a body na profi IT kurzy v soutěži ITnetwork summer 2017!
Přidej si svou IT školu do profilu a najdi spolužáky zde na síti :)

3. díl - Návštěvní kniha přes WebSocket - Zprovoznění komunikace

PHP Návštěvní kniha přes WebSocket Návštěvní kniha přes WebSocket - Zprovoznění komunikace

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulém tutoriálu seriálu Real-time návštěvní kniha přes WebSocket jsme implementovali jednoduchý Node.js server a začali s PHP serverem, kde jsme vytvořili hlavní třídu a autoloader. Dnes budeme pokračovat vytvořením třídy pro volání Node.js serveru a přidáme si slíbenou šablonu.

PHP/classes/Web­SocketApi.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/Ma­inClass.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:

Dotaz z PHP na Node.js

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:

Real-time obnovení stránky přes PHP a Node.js

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ích dílech aplikaci upravíme do plnohodnotné real-time knihy návštěv nebo chatu, chcete-li projekt tak nazývat.


 

 

Článek pro vás napsal Patrik Smělý (SogoCZE)
Avatar
Jak se ti líbí článek?
3 hlasů
Autor se věnuje front-end i back-end vývoji webových stránek, nejvíce pracuje s jazykem PHP a Javascript. Rád se učí nové věci a někdy strčí nos i do 3D / 2D grafiky.
Aktivity (1)

 

 

Komentáře
Zobrazit starší komentáře (3)

Avatar
reddi
Člen
Avatar
reddi:5.4.2016 16:21

Ahoj, jedničku to tam hází z metody mainMethod(), jelikož je na konci echo a include šablony se provede.

 
Odpovědět 5.4.2016 16:21
Avatar
shaman
Člen
Avatar
shaman:18.7.2016 0:02

Zaujimavy koncept.
Ako to planujes osetrit aby sa na ten websocket nemohol napojit hocikto a pocuvat?

Odpovědět 18.7.2016 0:02
try {...} catch (Exception ignored) { echo " ¯\_(ツ)_/¯ "; }
Avatar
Patrik Smělý (SogoCZE)
Tým ITnetwork
Avatar
Odpovídá na shaman
Patrik Smělý (SogoCZE):18.7.2016 0:26

Ahoj,

Pokud si myslel například ze svého webu kde budeš mít socket.io klienta tak je to jednoduché, ošetření je prováděno přes originy, jednoduše na serverové straně (NodeJs) nastavíš že se klienti můžou připojit jen z určité ip:portu / domény:portu implementace pak vypadá následovně. (Ze základu je připojení povoleno odkudkoliv)

io.set('origins', 'www.example.com:80');
Editováno 18.7.2016 0:27
Odpovědět 18.7.2016 0:26
PHP můj oblíbený jazyk......
Avatar
shaman
Člen
Avatar
Odpovídá na Patrik Smělý (SogoCZE)
shaman:18.7.2016 9:45

uzivatel nema origin. Uzivatel ma IP adresu. Na tej istej IP adrese je kopa ludi ktory nemaju alebo by nemali mat pristup k websocketu? V pripade knihy navstev je to ok, ale co ked budem robit chat? Ako by si to osetril?

Odpovědět 18.7.2016 9:45
try {...} catch (Exception ignored) { echo " ¯\_(ツ)_/¯ "; }
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na shaman
David Čápka:18.7.2016 9:51

Uživatel chatu bude registrovaný, bude mít nějaké ID.

Odpovědět  +1 18.7.2016 9:51
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
shaman
Člen
Avatar
Odpovídá na David Čápka
shaman:18.7.2016 10:06

takze id bude mat uzivatel nastavene napr. v session
a websocket bude mat zoznam povolenych ID ktorym ma propagovat spravy?

Odpovědět 18.7.2016 10:06
try {...} catch (Exception ignored) { echo " ¯\_(ツ)_/¯ "; }
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na shaman
David Čápka:18.7.2016 11:00

Přesně tak.

Odpovědět  +2 18.7.2016 11:00
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
Patrik Smělý (SogoCZE)
Tým ITnetwork
Avatar
Odpovídá na shaman
Patrik Smělý (SogoCZE):18.7.2016 13:48

Přímo uživatel mít origin nebude ale klient z jakého se připojuje origin má, takže pokud se uživatel připojí z webového klienta tak bude mít origin dané webové stránky, pokud se ale připojí například z localhostu - přes nějaký program či prostě z webu na localhostu tak jako origin bude mít svojí ip adresu.

Jinak jak psal David Čápka, při pokročilém ošetření je potřeba využít nějaký token, který bude vždy posílat uživatel při svém prvním připojením, server si následně daný token ověří a na základě toho bude dále posílat či neposílat tomuto uživateli sockety.

Odpovědět 18.7.2016 13:48
PHP můj oblíbený jazyk......
Avatar
Marek Unzeitig:7. července 2:17

Ahoj všichni,
mám stejný problém jako Dominik. Všechno mi funguje až na to zobrazování zpráv. Vyzkoušel jsem všemožné porty, ale pořád bez úspěchu. Nevíte někdo, čím by to mohlo být?
Jedu na Win7 + XAMPP

 
Odpovědět 7. července 2:17
Avatar
Marek Unzeitig:7. července 8:56

Tak už jsem našel řešení na to nezobrazování zpráv, nejspíš to bylo zastaralou verzí Socket.IO. Aktualizoval jsem na nejnovější verzi společně s jQuery a vše šlape jako hodinky.

Sorry že přidávám nový post, ten původní mi nešel editovat.

 
Odpovědět 7. července 8:56
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 13. Zobrazit vše