Vajíčková mánie Vajíčková mánie
Od 15. do 21.4. slevy 20 až 80% v sekci C/C++. Když ne teď, tak kdy?
Vyšlehej si extra vědomosti! Až 100% bodů na prémiový obsah zdarma! Více zde

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

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é 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 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í lekci, Návštěvní kniha přes WebSocket - Šablona aplikace, aplikaci dodáme hezčí kabát. A dále ji v kurzu 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ý
Avatar
Jak se ti líbí článek?
4 hlasů
Autor miluje filosofii, sci-fi, technologie, hry a hlavně svobodu. Aktivně se věnuje programování, designu, 3D grafice, správě sítí a trochu méně hardwaru. Mimo technologické zaměření se velice zajímá o politiku a psychologii.
Předchozí článek
Návštěvní kniha přes WebSocket - Server a hlavní PHP třída
Všechny články v sekci
Návštěvní kniha přes WebSocket
Miniatura
Následující článek
Návštěvní kniha přes WebSocket - Šablona aplikace
Aktivity (2)

 

 

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

Avatar
Patrik Smělý
Tým ITnetwork
Avatar
Patrik Smělý: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
Avatar
Marek Unzeitig:7.7.2017 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.7.2017 2:17
Avatar
Marek Unzeitig:7.7.2017 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  +1 7.7.2017 8:56
Avatar
tchosniper
Člen
Avatar
tchosniper:12.10.2017 21:28

Možná už mi tu nikdo neodpoví, ale neporadil by mi někdo jak to zabezpečit pomocí letsencrypt cert.? Hledal jsem snad úplně všude, ale třeba mi to napiše že Broken Htttps a tak..

 
Odpovědět 12.10.2017 21:28
Avatar
michaelmik
Člen
Avatar
michaelmik:14. února 12:32

Ahoj mám stejný problém jako Dominik Dosoudil, s tím že bohužel stále zde nikdo neodpověděl jaká tam je chyba. Na stránce se vypíše text "Povedlo se! Node.js vrací true!" ale už nevypíše zprávy který jsem poslal přes sendSocket(). Jedu pod XAMPP v linuxu - ubuntu a program jsem napsal stejně jako je v návodu. :) Díky za případnou odpověd :)

 
Odpovědět 14. února 12:32
Avatar
Patrik Smělý
Tým ITnetwork
Avatar
Odpovídá na michaelmik
Patrik Smělý:14. února 16:25

Ahoj, zkus prosím aktualizovat verzi knihovny Socket.IO na nejnovější :).

 
Odpovědět 14. února 16:25
Avatar
michaelmik
Člen
Avatar
michaelmik:15. února 7:49

To už jsem právě dávno udělal, bohužel nevím jestli správně, přes příkaz npm install socket.io .. :) bohužel po restartu serveru stále nic. :)

 
Odpovědět 15. února 7:49
Avatar
michaelmik
Člen
Avatar
Odpovídá na Patrik Smělý
michaelmik:25. února 10:00

Ahoj, tak jsem ještě vše zkusil napsat pod Win a bohužel taky nic. Jel jsem opět podle návodu zde a opět jen vyběhla hláška, že nodejs vrací true :). Bohužel nejsem si stále jistej jestli pro update socketu stačil příkaz "npm update socket.io" nebo mám napsat jiný příkaz? Děkuji za odpověd :)

 
Odpovědět 25. února 10:00
Avatar
Kara
Člen
Avatar
Kara:23. března 21:46

měla jsem stejný problém, nevracelo mi to zprávy, přitom server běžel, na stackoverflow jsem našla, že místo
<script src="https://­cdn.socket.io/soc­ket.io-1.2.0.js" charset="UTF-8"></script>

mám napsat

<script src="http://l­ocalhost:4000/soc­ket.io/socket­.io.js"></scrip­t>

od té doby to funguje :)

 
Odpovědět 23. března 21:46
Avatar
michaelmik
Člen
Avatar
Odpovídá na Kara
michaelmik:12. dubna 22:00

Ahoj hned jak budu moct tak tohle zkusim :)

Editováno 12. dubna 22:01
 
Odpovědět 12. dubna 22:00
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 20. Zobrazit vše