Tutoriel Vidéo Ruby on Rails Découverte d'ActionCable

Télécharger la vidéo Télécharger les sources

Ruby on Rails 5 est disponible depuis quelques semaines maintenant et intègre une nouveauté plutôt intéréssante : ActionCable. Ce nouvel outil permet d'intégrer un système de websocket à son application rails afin d'intégrer des notifications temps réel sur la page.

Principe de base

ActionCable repose sur le même principe que les Pub/Sub de Redis :

  • Un client va pouvoir s'abonner à différents canaux
  • Le serveur va alors pouvoir publier sur un canal un message, qui sera alors automatiquement envoyés aux clients abonnés.

Ce système permet de mettre en place rapidement un système de notification instantanné mais quelques points sont à noter :

  • Si un client se déconnecte d'un canal, il ne recevra pas les alertes manquées lorsqu'il se reconnectera.
  • La navigation du site doit se faire en Ajax pour éviter que l'utilisateur se trouve déconnecter à chaque chargement de page.

Fonctionnement

Comme pour le reste des composants de Rails il existe une commande pour générer un canal et le code côté client :

rails g channel demo

Cette commande aura pour effet de créer un fichier /app/channels/demo_channel.rb et /app/assets/javascripts/channels/demo.coffee qui servent respectivement au serveur et au client.

La partie Ruby va être chargé de "broadcaster" les messages d'un canal et pourra, le cas échéant, émettre sur un canal particulier :

class DemoChannel < ApplicationCable::Channel

  def subscribed
    stream_from 'demo'
  end

  def speak(data)
      ActionCable.server.broadcast 'demo', message: data.message
  end

end

Côté front, l'utilisateur va pouvoir s'abonner au canal créé par cette classe et intéragir avec les méthodes publiques :

App.demo = App.cable.subscriptions.create "DemoChannel",
  connected: ->
    $(document).on 'keypress', '#message', (event) =>
      if event.keyCode is 13
        @perform 'speak', {message: message}
        event.target.value = ""
        event.preventDefault()

  disconnected: ->
    # Called when the subscription has been terminated by the server

  received: (data) ->
    $('#messages').append(data.message)