+ All Categories
Home > Software > WebSockets - how to do real-time applications in PHP

WebSockets - how to do real-time applications in PHP

Date post: 22-Jun-2015
Category:
Upload: brnophp
View: 435 times
Download: 3 times
Share this document with a friend
Description:
At Brno PHP April 2014 meetup by Ondřej Mirtes
31
WebSockety Ondřej Mirtes
Transcript
Page 1: WebSockets - how to do real-time applications in PHP

WebSocketyOndřej Mirtes

Page 2: WebSockets - how to do real-time applications in PHP

Využitelné všude tam, kde teď máte periodické AJAX požadavky$chat, notifikace, hry, realtime updates…

Page 3: WebSockets - how to do real-time applications in PHP

Počáteční HTTP handshake, poté stálé spojení přes TCP.$V komunikaci se posílají jen změny (v AJAXu obvykle celý stav aplikace).

Page 4: WebSockets - how to do real-time applications in PHP

caniuse.com

Page 5: WebSockets - how to do real-time applications in PHP

Detekce podpory

return  'WebSocket'  in  window;

Nekontrolujte typ a verzi prohlížeče, ale vždy výskyt konkrétní funkcionality.

Page 6: WebSockets - how to do real-time applications in PHP

var  ws  =  new  WebSocket('ws://localhost:8080');  $ws.onopen  =  function()  {  $};  $ws.onmessage  =  function(event)  {      console.log(event.data);  

};  $ws.onclose  =  function()  {  $};

Pozor - připojuje už konstruktor!

Page 7: WebSockets - how to do real-time applications in PHP

var  ws  =  new  WebSocketWrapper(     'ws://localhost:8080'  );  ws.connect();  $ws.on('postLiked',  function(data)  {      });  $ws.on('chatMessage',  function(data)  {  $});  $ws.send({'action':'ping'});

https://gist.github.com/10647722

Můj vlastní wrapper, který řeší reconnecting a rozstřelování konkrétních akcí do jednotlivých callbacků (oproti jedinému "onmessage").

Page 8: WebSockets - how to do real-time applications in PHP

Zakažte uživateli provádět akce při

uzavřeném spojení

Hrozí ztráta dat.

Page 9: WebSockets - how to do real-time applications in PHP

Proč WebSockety v PHP a ne v něčem vhodnějším, třeba node.js?$$Pokud máte už běžící aplikaci, tak napsáním WS funkcionality v PHP budete těžit z jednotné codebase, využití znalostí týmu a stejných procesů na testování, continuous integration, build a deployment.$$Pokud stavíte na zelené louce a chcete se naučit něco nového, tak vás do PHP nutit nebudu :)

Page 10: WebSockets - how to do real-time applications in PHP
Page 11: WebSockets - how to do real-time applications in PHP

$loop  =  React\EventLoop\Factory::create();  $socket  =  new  React\Socket\Server($loop);  $http  =  new  React\Http\Server($socket,  $loop);  $$http-­‐>on('request',  function($request,  $response)  {     $response-­‐>writeHead(       200,       ['Content-­‐Type'  =>  'text/plain']     );     $response-­‐>end("Hello  World\n");  });  $$socket-­‐>listen(1337);  $loop-­‐>run();

http://u.k47.cz/2Bw

Page 12: WebSockets - how to do real-time applications in PHP

while  (true)  {     ...  }

Event loop

http://u.k47.cz/2Bw

Request 1

Response 1

Request 2

Response 2

Request 3

Response 3

Request 4

Response 4

React je asynchronní, ale ne paralelní – běží stále v jednom vlákně.

Page 13: WebSockets - how to do real-time applications in PHP

while  (true)  {     ...  }

Event loop

http://u.k47.cz/2Bw

Response 1Response 2

Response 3

sleep(15);

Request 2 Request 3Request 1

Page 14: WebSockets - how to do real-time applications in PHP

http://socketo.me/

Page 15: WebSockets - how to do real-time applications in PHP

composer.json{          "require":  {                  "cboden/Ratchet":  "~0.3"          },          "suggest":  {                  "ext-­‐libevent":  ""          }  }

S libevent rozšířením se použije efektivnější implementace event loop.

Page 16: WebSockets - how to do real-time applications in PHP

use  Ratchet\Http\HttpServer;  use  Ratchet\Server\IoServer;  use  Ratchet\WebSocket\WsServer;  use  React\EventLoop\Factory;  use  React\Socket\Server;  $$loop  =  Factory::create();  $server  =  new  Server($loop);  $server-­‐>listen(8080,  '0.0.0.0');  $new  IoServer(     new  HttpServer(new  WsServer($app)),     $server  );  $$loop-­‐>run(); Spuštěný proces spravujte např. pomocí

supervisord.org, aby stále běžel.

Page 17: WebSockets - how to do real-time applications in PHP

use  Ratchet\ConnectionInterface  as  Client;  $class  App  implements  \Ratchet\MessageComponentInterface  {  $   public  function  onOpen(Client  $client)  {  $   }  $   public  function  onMessage(Client  $client,  $message)  {  $   }  $   public  function  onClose(Client  $client)  {         }  $   public  function  onError(Client  $client,  \Exception  $e)  {  $   }  $}

Page 18: WebSockets - how to do real-time applications in PHP

public  function  onMessage(Client  $client,  $message)  {          foreach  ($this-­‐>clients  as  $c)  {                  if  ($c  !==  $client)  {                          $c-­‐>send($message);                  }          }  }

Rozeslání zprávyna ostatní klienty

Page 19: WebSockets - how to do real-time applications in PHP

Při navázání spojení pošlete klientovi počáteční stav

Např. posledních 10 zpráv v chatu. Pokud byste počáteční stav nepotřebovali, tak vlastně nepotřebujete ani žádné úložiště na data.

Page 20: WebSockets - how to do real-time applications in PHP

Časovače

$loop-­‐>addTimer(5,  function()  {          //  za  pět  sekund  });  $$loop-­‐>addPeriodicTimer(5,  function()  {          //  každých  pět  sekund  });

Na odpojení uživatele při neaktivitě, na zasílání pingu pro udržení připojení. Časovače jsou jen v paměti, po pádu a obnovení procesu je musíte zrekonstruovat.

Page 21: WebSockets - how to do real-time applications in PHP

Flash polyfillhttps://github.com/gimite/web-socket-js

Page 22: WebSockets - how to do real-time applications in PHP

use  Ratchet\Server\FlashPolicy;  use  Ratchet\Server\IoServer;  use  React\Socket\Server;  $$server  =  new  Server($loop);  $server-­‐>listen(843,  '0.0.0.0');  $policy  =  new  FlashPolicy();  $policy-­‐>addAllowedAccess('*',  8080);  $new  IoServer($policy,  $server);  $loop-­‐>run();

FlashPolicy

Page 23: WebSockets - how to do real-time applications in PHP

Long pollingAJAX fallback, který funguje všude$

POST požadavky pro odchozí zprávy$

Stream příchozích zpráv přes dlouhodobý GET požadavek$

xhr.responseText & xhr.onreadystatechange

Page 24: WebSockets - how to do real-time applications in PHP

Ratchet

Long polling server

WS

WS

HTTP

https://gist.github.com/10895929

Long polling server = HTTP serverv PHP + WebSocket klient v PHP :)

Page 25: WebSockets - how to do real-time applications in PHP

Ratchet neumí SSL (wss://)$

Webserver může fungovat jako proxy,která zabezpečenou komunikaci zajistí$

Webserver může WebSockety poskytnoutna klasických portech (80 a 443) – např. na subdoméně$

Apache – mod_proxy_wstunnel

Page 26: WebSockets - how to do real-time applications in PHP

Ratchet

ws.foo.com wslp.foo.com www.foo.com

Long polling

Nginx jako proxy může všechny služby poskytnout na klasických portech – 80, 443.

Page 27: WebSockets - how to do real-time applications in PHP

http://zeromq.org/

Page 28: WebSockets - how to do real-time applications in PHP

Webserver

CLI

Ratchet

WebSocket klienti

Ratchet běží v odděleném procesu, pokud potřebujete reagovat na akci z webové aplikace nebo třeba cronu, pošlete ji do Ratchetu pomocí ZMQ.

Page 29: WebSockets - how to do real-time applications in PHP

ZeroMQ - receiver

use  React\ZMQ\Context;  $$context  =  new  Context($loop);  $socket  =  $context-­‐>getSocket(ZMQ::SOCKET_PULL);  $socket-­‐>bind('tcp://127.0.0.1:5555');  $socket-­‐>on('message',  [$app,  'onZmqMessage']);

Page 30: WebSockets - how to do real-time applications in PHP

ZeroMQ - sender

$context  =  new  ZMQContext();  $socket  =  $context-­‐>getSocket(     ZMQ::SOCKET_PUSH,     'id'  );  $socket-­‐>connect('tcp://127.0.0.1:5555');  $socket-­‐>send('ahoj!');

Page 31: WebSockets - how to do real-time applications in PHP

@OndrejMirtes


Recommended