Phoenix LiveView
Web interactif côté serveur
Architecture initiale
HTML + JS
Serveur web
Navigateur
Application Javascript
HTML JSON
HTML + JS
Framework Javascript
Une autre approche?
HTML + JS
Websocket
Phoenix LiveView
Elixir
Phoenix
Websockets
Code d’une LiveView
defmodule MyAppWeb.HelloWorldLive do
use Phoenix.LiveView
def mount(_session, socket) do
{:ok, assign(socket, message: "Hello WAQ!!!")}
end
def render(assigns) do
~L"""
<div>Message: <%= @message %></div>
"""
end
end
Code d’une LiveView
defmodule MyAppWeb.HelloWorldLive do
use Phoenix.LiveView
def mount(_session, socket) do
{:ok, assign(socket, message: "Hello WAQ!!!")}
end
def render(assigns) do
~L"""
<div>Message: <%= @message %></div>
"""
end
end
Code d’une LiveView
defmodule MyAppWeb.HelloWorldLive do
use Phoenix.LiveView
def mount(_session, socket) do
{:ok, assign(socket, message: "Hello WAQ!!!")}
end
def render(assigns) do
~L"""
<div>Message: <%= @message %></div>
"""
end
end
Utiliser une LiveView
# Template
<%= Phoenix.LiveView.live_render(@conn, DemoWeb.HelloWorldLive ) %>
# Routeur
live "/hello", DemoWeb.HelloWorldLive
# Controlleur
Phoenix.LiveView.Controller.live_render(conn, DemoWeb.HelloWorldLive )
Ajouter de l’interactivité
def render(assigns) do
~L"""
<div>Message: <%= @message %></div>
<button phx-click="add_message">
Ajouter WAQ!!!
</button>
"""
end
def handle_event("add_message", _value, socket) do
message = socket.assigns.message <> "WAQ!!!"
{:noreply, assign(socket, message: message)}
end
Ajouter de l’interactivité
def render(assigns) do
~L"""
<div>Message: <%= @message %></div>
<button phx-click="add_message">
Ajouter WAQ!!!
</button>
"""
end
def handle_event("add_message", _value, socket) do
message = socket.assigns.message <> "WAQ!!!"
{:noreply, assign(socket, message: message)}
end
Fonctionnement
GET /home
HTML + JS
liveSocket.connect()
Socket connecté
phx-click
Fragments HTML
Réponse serveur
["1", "4", "lv:phx-FHOaenCt", "phx_reply", {
"response": {
"diff": {
"0": "Hello WAQ!!!WAQ!!!WAQ!!!"
}
},
"status": "ok"
}]
Partager des informations entre les utilisateurs
def mount(_session, socket) do
Phoenix.PubSub.subscribe(MyApp.PubSub, "topic")
{:ok, assign(socket, message: "Hello WAQ!!!" )}
end
def handle_info(%{message: message}, socket) do
{:noreply, assign(socket, message: message)}
end
def handle_event("add_message", _value, socket) do
message = socket.assigns.message <> "WAQ!!!"
Phoenix.PubSub.broadcast(MyApp.PubSub, "topic", %{message: message})
{:noreply, socket}
end
Partager des informations entre les utilisateurs
def mount(_session, socket) do
Phoenix.PubSub.subscribe(MyApp.PubSub, "topic")
{:ok, assign(socket, message: "Hello WAQ!!!")}
end
def handle_info(%{message: message}, socket) do
{:noreply, assign(socket, message: message)}
end
def handle_event("add_message", _value, socket) do
message = socket.assigns.message <> "WAQ!!!"
Phoenix.PubSub.broadcast(MyApp.PubSub, "topic", %{message: message})
{:noreply, socket}
end
Partager des informations entre les utilisateurs
def mount(_session, socket) do
Phoenix.PubSub.subscribe(MyApp.PubSub, "topic")
{:ok, assign(socket, message: "Hello WAQ!!!")}
end
def handle_info(%{message: message}, socket) do
{:noreply, assign(socket, message: message)}
end
def handle_event("add_message", _value, socket) do
message = socket.assigns.message <> "WAQ!!!"
Phoenix.PubSub.broadcast(MyApp.PubSub, "topic", %{message: message})
{:noreply, socket}
end
Résultat
Avantages
Simple
Performant
Temps réel
Limitations
Pas de “hors-ligne”
Latence
Mémoire serveur
Cas d’utilisation
Formulaires dynamiques
Tableaux de bord
Outils collaboratifs
Jeux multijoueur
Conclusion
HTML + JS
Websocket

Frédérick Capovilla

  • 1.
  • 2.
    Architecture initiale HTML +JS Serveur web Navigateur
  • 3.
    Application Javascript HTML JSON HTML+ JS Framework Javascript
  • 4.
  • 5.
  • 6.
    Code d’une LiveView defmoduleMyAppWeb.HelloWorldLive do use Phoenix.LiveView def mount(_session, socket) do {:ok, assign(socket, message: "Hello WAQ!!!")} end def render(assigns) do ~L""" <div>Message: <%= @message %></div> """ end end
  • 7.
    Code d’une LiveView defmoduleMyAppWeb.HelloWorldLive do use Phoenix.LiveView def mount(_session, socket) do {:ok, assign(socket, message: "Hello WAQ!!!")} end def render(assigns) do ~L""" <div>Message: <%= @message %></div> """ end end
  • 8.
    Code d’une LiveView defmoduleMyAppWeb.HelloWorldLive do use Phoenix.LiveView def mount(_session, socket) do {:ok, assign(socket, message: "Hello WAQ!!!")} end def render(assigns) do ~L""" <div>Message: <%= @message %></div> """ end end
  • 9.
    Utiliser une LiveView #Template <%= Phoenix.LiveView.live_render(@conn, DemoWeb.HelloWorldLive ) %> # Routeur live "/hello", DemoWeb.HelloWorldLive # Controlleur Phoenix.LiveView.Controller.live_render(conn, DemoWeb.HelloWorldLive )
  • 10.
    Ajouter de l’interactivité defrender(assigns) do ~L""" <div>Message: <%= @message %></div> <button phx-click="add_message"> Ajouter WAQ!!! </button> """ end def handle_event("add_message", _value, socket) do message = socket.assigns.message <> "WAQ!!!" {:noreply, assign(socket, message: message)} end
  • 11.
    Ajouter de l’interactivité defrender(assigns) do ~L""" <div>Message: <%= @message %></div> <button phx-click="add_message"> Ajouter WAQ!!! </button> """ end def handle_event("add_message", _value, socket) do message = socket.assigns.message <> "WAQ!!!" {:noreply, assign(socket, message: message)} end
  • 12.
    Fonctionnement GET /home HTML +JS liveSocket.connect() Socket connecté phx-click Fragments HTML
  • 13.
    Réponse serveur ["1", "4","lv:phx-FHOaenCt", "phx_reply", { "response": { "diff": { "0": "Hello WAQ!!!WAQ!!!WAQ!!!" } }, "status": "ok" }]
  • 14.
    Partager des informationsentre les utilisateurs def mount(_session, socket) do Phoenix.PubSub.subscribe(MyApp.PubSub, "topic") {:ok, assign(socket, message: "Hello WAQ!!!" )} end def handle_info(%{message: message}, socket) do {:noreply, assign(socket, message: message)} end def handle_event("add_message", _value, socket) do message = socket.assigns.message <> "WAQ!!!" Phoenix.PubSub.broadcast(MyApp.PubSub, "topic", %{message: message}) {:noreply, socket} end
  • 15.
    Partager des informationsentre les utilisateurs def mount(_session, socket) do Phoenix.PubSub.subscribe(MyApp.PubSub, "topic") {:ok, assign(socket, message: "Hello WAQ!!!")} end def handle_info(%{message: message}, socket) do {:noreply, assign(socket, message: message)} end def handle_event("add_message", _value, socket) do message = socket.assigns.message <> "WAQ!!!" Phoenix.PubSub.broadcast(MyApp.PubSub, "topic", %{message: message}) {:noreply, socket} end
  • 16.
    Partager des informationsentre les utilisateurs def mount(_session, socket) do Phoenix.PubSub.subscribe(MyApp.PubSub, "topic") {:ok, assign(socket, message: "Hello WAQ!!!")} end def handle_info(%{message: message}, socket) do {:noreply, assign(socket, message: message)} end def handle_event("add_message", _value, socket) do message = socket.assigns.message <> "WAQ!!!" Phoenix.PubSub.broadcast(MyApp.PubSub, "topic", %{message: message}) {:noreply, socket} end
  • 17.
  • 18.
  • 19.
  • 20.
    Cas d’utilisation Formulaires dynamiques Tableauxde bord Outils collaboratifs Jeux multijoueur
  • 21.