Utilisation des WebSockets avec Laravel 5.3

AFUP Lyon /

Qui suis-je ?
Consultant indépendant

Développements d'applications, de sites, constitution d'équipes, accompagnement, méthodes agiles...

  https://chstudio.fr

  s.hulard@chstudio.fr

  @s_hulard

  http://github.com/shulard

Les 10 prochaines minutes...

  1. WebSockets ?
  2. Laravel ?
  3. Et concrètement ?


WebSockets ?

Protocole de communication

  • Standardisé en 2011 par l'IETF dans la RFC6455
  • Communication bidirectionnelle Client ↔ Serveur
  • Communication temps réel, la connection reste ouverte

  • Utilise une requête HTTP pour réaliser le handshake :
    • Upgrade de HTTP à WS
    • Autorisation de la connection

Implémentation

  • Côté client (navigateur) :
    • API JavaScript pour envoyer recevoir des messages
    • Bien supporté aujourd'hui :
      • IE10+, Edge, Firefox, Chrome, Safari, Opera...
      • Et sur mobile aussi, seul mauvais élève : Opera Mini
  • Côté serveur :
    • Programme d'écoute pour le handshake
    • Programme d'écoute / réponse de messages

http://caniuse.com/#feat=websockets

Préférer la simplicité

Zoom sur : Socket.io

  • Solution Open Source
  • Propose une implémentation client et serveur
  • Gère un fallback en long polling Ajax
  • Outil solide et maintenu par une grande communauté
  • Développé en JavaScript


Laravel ?

“The PHP Framework For Web Artisans”

  • Framework PHP créé par Taylor Otwell en 2011
  • Développement d'applications web en utilisant MVC
  • Basé sur le module HTTPKernel de Symfony 2
  • Eloquent ORM : ActiveRecord pour la base de données

Version 5.3 ?

  • Sortie en août 2016
  • Trois nouveaux modules :
    • Scout : Recherche Full Text intégrée
    • Passport : OAuth 2 server
    • Echo : Event broadcasting → 🎉

La promesse de Laravel Echo

Apporter la puissance des WebSockets
dans votre application sans la complexité !

Et concrètement ?

Dans le code PHP

  • Création d'un objet Event
  • Implémentation de l'interface : ShouldBroadcast
  • Envoi des évenements vers le client avec la fonction broadcast

Super facile 👍

https://laravel.com/docs/5.3/broadcasting

Exemple dans un contrôleur

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Event\UserMessageCreated;

class UserController extends Controller
{
    public function createMessage(Request $request)
    {
        $message = new App\Message($request->all());
        $message->save();

        broadcast(new UserMessageCreated($request->user(), $message));
    }
}
						
<?php

namespace App\Events;

use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class UserMessageCreated implements ShouldBroadcast
{
    use SerializesModels;

    public $user;
    public $message;

    public function __construct(App\User $user, App\Message $message)
    {
        $this->user = $user;
        $this->message = $message;
    }

    public function broadcastOn()
    {
        return new PrivateChannel('user.'.$this->user->id);
    }
}
						

Quelques précisions

  • Les évenements émis sont placés dans une file d'attente (queue)
  • Il faut choisir son driver: BDD, Redis, SQS, Beanstalk...
  • Par défaut c'est “sync” mais attention à l'impact sur les temps de réponse de l'application

Quelques précisions

  • Il faut aussi un driver de broadcast :
    • Pusher, Redis, Log, Null

  • Pusher ? C'est le seul driver de WebSocket !!
    • Et c'est un service SAAS payant...

  • Redis sert de passerelle vers d'autres solutions...

Pour une implémentation locale

  • Pas de solution en PHP pour l'instant...
  • Obligé de passer par un serveur de WebSocket en JavaScript :

  • ⚠ Pas de communication Client → Serveur possible

Schéma d'architecture

⚠ Le socle technique devient complexe.

Et en front ?

  • Taylor Otwell a publié un client JavaScript spécifique : laravel/echo
    • Code simple et accessible pour écouter et réagir aux évènements
    • Approche similaire à l'API native WebSocket
    • ⚠ Packagé par défaut avec le client Pusher...
  • En n'utilisant pas Pusher, la stabilité est relative :
    • Par exemple obligation de forcer une version spécifique pour que ça fonctionne.

Bilan

  • L'application développée fonctionne aujourd'hui correctement
  • L'utilisation d'AJAX pour les messages Client → Serveur n'est pas idéal
  • L'implémentation manque de maturité
  • L'installation et la maintenance sont beaucoup plus complexes que prévu

Questions ?

http://shulard.github.io/talks/afup-lyon-lighting-décembre-2016