Laravel, ReactPHP & Ratchet

Qué es y cómo integrarlo en nuestro proyecto Laravel

Código: https://github.com/glena/reactdemo

Video: https://www.youtube.com/watch?v=_avhGaq9-Bg


Germán Lena / @german_lena

¿Qué es ReactPHP?

  • Event-driven, non-blocking I/O with PHP.
  • Programación basada en eventos.
  • Single thread, asincronico, no bloqueante.
  • Basado en "Reactor pattern" (patron de diseño de programación concurrente).

Internamente

  • Core basado en biblioteca de Streams de PHP.
  • Main event loop: stream_select (duerme el proceso hasta que un socket se activa).
  • Altamente inspirado en Node.js

Ratchet

  • Implementa Websockets sobre ReactPHP.
  • Provee un stack de componentes (I/O, HTTP, WS, SESSION, WAMP, APP).
  • Similar a SocketIO (NodeJS)

Hagamos un chat bien simple

  • SPA hecha el Laravel
  • Ratchet + React para las comunicaciones

Creemos el Servidor Web Sockets

  • En un nuevo workbench (para abstraerlo del codigo de la app)
  • php artisan workbench autor/paquete

Estructura

  • Command: va a hacer el bootstrap del servidor.
  • Manager: va a manejar las conexiones.
  • UserConnection: va a representar cada una de las conexiones.

Command

										
public function __construct(ManagerInterface $manager)
    {
        parent::__construct();

        $this->manager = $manager;

        $this->manager->getEmitter()->on("open",
          function(UserConnectionInterface $user)
          {
              $this->line("
                  #{$user->getId()} connected.
              ");
          }
        );
        
        ...
										
								

Command

										
$port = (integer) Config::get('app.streams_port');

$server = IoServer::factory(
    new HttpServer(
        new WsServer(
            $this->manager
        )
    ),
    $port
);
  
$server->run();
										
								

UserConnection

Conexión desde JS

										

var socket = new WebSocket("ws://127.0.0.1:7778/");
socket.addEventListener("open", function (e) {
    console.log("open: ", e);
});
socket.addEventListener("error", function (e) {
    console.log("error: ", e);
});
socket.addEventListener("message", function (e) {
    console.log("message: ", JSON.parse(e.data));
});
socket.send('{"message":"hello!"}');

										
								

FIN

Referencias

  • http://reactphp.org/ (miren los videos!!)
  • http://socketo.me (Ratchet)
  • https://medium.com/laravel-4/laravel-4-real-time-chat-eaa550829538
  • http://es.wikipedia.org/wiki/State_(patr%C3%B3n_de_dise%C3%B1o) (state pattern)