SlideShare une entreprise Scribd logo
Phoenix Presence: Le service temps
réel de Phoenix 1.2
Mickaël Rémond
ProcessOne
Brève histoire de Phoenix
Qu'est-ce que Phoenix ?
Framework de développement Web
Développement lancé en août 2014 avec un focus sur les websockets
Inspiration venant de différents frameworks: Ruby on Rails, Clojure Ring, Scala
Playframework, ...
Version 1.0 sortie en août 2015.
Version 1.1 en décembre 2015.
Version 1.2 majeure en juin 2016.
Les atouts de Phoenix
Points forts:
Élégance grâce à la syntaxe d'Elixir et à son système de macros (DSL)
Performance et clustering grâce à la VM Erlang
Productivité avec des outils de base de données comme Ecto
Fonctionnalités:
couvre le support des pages web dynamiques.
interactions temps réel: websockets et presence.
De Phoenix 1.0 à Phoenix 1.2
Phoenix 1.1:
Amélioration des performances des channels
Localisation via Gettext
Phoenix 1.2:
Ecto 2.0
Phoenix Presence
Références
Introduction au développement Web avec le framework Phoenix
www.youtube.com/watch?v=GPF6w3CsWio(https://www.youtube.com/watch?v=GPF6w3CsWio)
Site Web de Phoenix
www.phoenixframework.org(http://www.phoenixframework.org)
Websockets, Channels, Presence: Les concepts
Définitions
Websockets: protocole de communication entre le navigateur et le serveur. Maintiens la
connexion pendant la durée de la session.
Channels: Les channels définisset le comportement du serveur pour le broadcast de
message en temps réel, par "sujet" (topic).
Presence: Le module de "présence tracker synchronize l'état des joins et des leaves de
sur les topics, via le module channel, et broadcast les changements.
Architecture
Presence vs Channels ?
La fonctionnalité de Phoenix Presence vient sous la forme d'un presence tracker.
Il s'agit d'une structure de données en mémoire, répliquée et synchronisée en
temps réel sur tous les noeuds d'un cluster Elixir.
Elle s'appuie sur les channels:
pour recevoir les événements de join et de leave.
pour envoyer l'état initial et les mises à jour incrémentales.
Phoenix Presence permet:
la découverte de service / composants du système.
la gestion de la présence des utilisateurs.
Points forts de Phoenix Presence
Robustesse:
Réplication en temps réel sur l'ensemble du cluster.
pas de point de failure unique (SPOF).
peut continuer à fonctionner lors d'un netsplit.
supporte de fortes charges.
Simplicité:
de gestion: gère la réconciliation automatiquement lorsque le cluster se reconstitue.
de déploiement: dépends uniquement de module standard, sans dépendance externe.
d'implémentation: est fourni avec un module Javascript pour faciliter l'implémentation
des clients.
Limitations
Phoenix Presence est une structure de données distribuée. Les fonctionnalités restent
d'assez bas niveau.
Il est idéal pour gérer la présence en temps réel pour des communautés:
Site web
Jeu vidéo
Il reste un système simple, fonctionnant sur la base de topic et de channels:
Pas de liste de contacts / présence individuelle.
Mise en œuvre
L'exemple Gastronokids
Application d'illustration utilisée dans ma précédente présentation sur Phoenix.
github.com/ElixirParis/gastronokids(https://github.com/ElixirParis/gastronokids)
Enrichissement pour ajouter un module de présence.
Étape 1: Mise à jour de Phoenix 1.0 à Phoenix 1.2
Changements
Résumé:
Migration vers Postgres: SQLite Ecto ne fonctionne pas encore avec Ecto 2.0
Mise à jour des dépendances Elixir et Javascript
Mise à jour vers Ecto 2.0: Model -> Schema
Ajout du support de la localisation Gettext
Changement du code de gestion des erreurs dans les formulaires
Commit complet:
Github: Migrate for Phoenix 1.0 to Phoenix 1.2 + move to Postgres
(https://github.com/ElixirParis/gastronokids/commit/418e10926c7e647b47628d2006a91123496a57da)
Étape 2: Ajout du module de présence
Générer le code du module Presence
Utilisation du scaffolding pour générer le code:
$ mix phoenix.gen.presence
* creating web/channels/presence.ex
Add your new module to your supervision tree,
in lib/gastronokids.ex:
children = [
...
supervisor(Gastronokids.Presence, []),
]
You're all set! See the Phoenix.Presence docs for more details:
http://hexdocs.pm/phoenix/Phoenix.Presence.html
Nous utilisons le module en l'état.
Configuration
Ajouter le service de présence dans l'application
Dans lib/gastronokids.ex, ajout du module dans l'arbre de supervision:
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
# Start the endpoint when the application starts
supervisor(Gastronokids.Endpoint, []),
# Start the Ecto repository
worker(Gastronokids.Repo, []),
# Presence tracker:
supervisor(Gastronokids.Presence, []),
]
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: Gastronokids.Supervisor]
Supervisor.start_link(children, opts)
end
Config PubSub
Vérifier que le service PubSub est bien configuré dans config/config.exs:
config :gastronokids, Gastronokids.Endpoint,
url: [host: "localhost"],
secret_key_base: "j458rtSt4qQnUmBDEVmjX3X6tCtLLjWJy6rhO58WO86s1S2I3i4zePgdcV/T3N41",
render_errors: [view: Gastronokids.ErrorView, accepts: ~w(html json)],
# This is mapping between name and pubsub backend
pubsub: [name: Gastronokids.PubSub,
adapter: Phoenix.PubSub.PG2]
room_channel.ex
Lier la présence aux channels (1/2)
Importer notre module de présence dans web/channel/room_channel.ex:
defmodule Gastronokids.RoomChannel do
use Gastronokids.Web, :channel
alias Gastronokids.Presence
Déclencher un événement de join asynchrone:
def join("rooms:lobby", payload, socket) do
if authorized?(payload) do
send self(), :after_join
{:ok, socket}
else
{:error, %{reason: "unauthorized"}}
end
end
Lier la présence aux channels (2/2)
Garder la trace de la présence après le join et broadcast de la liste initiale:
def handle_info(:after_join, socket) do
Presence.track(socket, socket.assigns.user_id, %{
device: "browser",
online_at: inspect(:os.timestamp())
})
push socket, "presence_state", Presence.list(socket)
{:noreply, socket}
end
Note: Il n'est pas nécessaire de gérer la déconnexion / leave. Channels et Presence gèrent
cela pour le développeur.
Broadcast des messages de chat
Le callback handle_in sert toujours à assurer la diffusion des messages de chat:
def handle_in("new_msg", payload, socket) do
payloadWithUser = %{"body" => payload["body"], "user": socket.assigns.user_id}
broadcast! socket, "new_msg", payloadWithUser
{:noreply, socket}
end
Le callback handle_out n'est pas nécessaire, car nous utilisons l'implémentation par défaut.
user_socket.ex
Assigner le user_id à la socket
Nous étendons la fonction connect/2 dans web/channels/user_socket.ex:
def connect(%{"user_id" => id}, socket) do
{:ok, assign(socket, :user_id, id)}
end
Le client Javascript socket.js
Mise en place socket / présence
Dans web/static/js/socket.js, nous importons Socket et Presence, et créons une
nouvelle socket:
import {Socket, Presence} from "phoenix"
let socket = new Socket("/socket", {params: {token: window.userToken, user_id: window.userId}})
Nous lançons la connexion et initialons l'environnement:
socket.connect()
let channel = socket.channel("rooms:lobby", {})
let presences = {}
Gestion des événements de présence
La lib Phoenix Presence Javascript gère l'état des présences pour le développeur:
channel.on("presence_state", state => {
presences = Presence.syncState(presences, state)
render(presences)
})
channel.on("presence_diff", diff => {
presences = Presence.syncDiff(presences, diff)
render(presences)
})
Afficher la liste de présence
La lib Phoenix Presence Javascript permet de récupérer et trier la liste des présences:
let listBy = (id, {metas: [first, ...rest]}) => {
first.name = id
first.count = rest.length +1
return first
}
let render = (presences) => {
let onlineUsers = Presence.list(presences, listBy)
let htmlList = onlineUsers
.map(user => `<li>${user.name} (${user.count})</li>`)
.join("")
userList.html(htmlList)
}
Gestion des messages
Pour finir, nous gérer la réception et l'envoi des messages:
channel.on("new_msg", payload => {
var now = new Date();
messagesContainer.append(`<br/>[${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}] ${payload.use
})
chatInput.on("keypress", event => {
if(event.keyCode === 13){
channel.push("new_msg", {body: chatInput.val()})
chatInput.val("")
}
})
L'interface utilisateur
Mise en place du code HTML
Notre code fournit des éléments conteneurs pour les utilisateurs présents et le chat:
<p>Online Users:</p>
<ul id="user-list"></ul>
<div class="chat">
<div id="messages"></div>
<input id="chat-input" type="text"></input>
</div>
Pour simplifier, le nom de l'utilisateur vient des paramètres de la page:
<script>
window.userId = "<%= if @conn.params["name"], do: @conn.params["name"], else: "Anonymous" %>"
</script>
Démo
localhost:4000/?name=Micka%C3%ABl(http://localhost:4000/?name=Micka%C3%ABl)
localhost:4000/?name=JohnDoe(http://localhost:4000/?name=JohnDoe)
localhost:4000/?name=Steve(http://localhost:4000/?name=Steve)
Télécharger le code
Github Gastronokids
github.com/ElixirParis/gastronokids(https://github.com/ElixirParis/gastronokids)
Conclusion
L'ajout du module de Presence complète les channels de Phoenix de manière
redoutablement efficace.
Avec cet ajout, Phoenix devient l'outil le plus complet pour implémenter des applications
web temps réel reliant:
Base de données.
Système de templating de pages.
Mise à jour temps réel via un outillage Javascript complet.
Et tout cela, dans un package unique, sans dépendance.
Thank you
Mickaël Rémond
ProcessOne
mremond@process-one.net(mailto:mremond@process-one.net)
http://www.process-one.net/(http://www.process-one.net/)
@mickael(http://twitter.com/mickael)
Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8

Contenu connexe

En vedette

IoT Studio #1: Protocols introduction and connected jukebox
IoT Studio #1: Protocols introduction and connected jukeboxIoT Studio #1: Protocols introduction and connected jukebox
IoT Studio #1: Protocols introduction and connected jukebox
Mickaël Rémond
 
XMPP Academy #3
XMPP Academy #3XMPP Academy #3
XMPP Academy #3
Mickaël Rémond
 
Deep Dive Into ejabberd Pubsub Implementation
Deep Dive Into ejabberd Pubsub ImplementationDeep Dive Into ejabberd Pubsub Implementation
Deep Dive Into ejabberd Pubsub Implementation
Mickaël Rémond
 
Managing ejabberd Platforms with Docker - ejabberd Workshop #1
Managing ejabberd Platforms with Docker - ejabberd Workshop #1Managing ejabberd Platforms with Docker - ejabberd Workshop #1
Managing ejabberd Platforms with Docker - ejabberd Workshop #1
Mickaël Rémond
 
Create Your Own Language
Create Your Own LanguageCreate Your Own Language
Create Your Own Language
Hamidreza Soleimani
 
Event Driven Architecture Concepts in Web Technologies - Part 2
Event Driven Architecture Concepts in Web Technologies - Part 2Event Driven Architecture Concepts in Web Technologies - Part 2
Event Driven Architecture Concepts in Web Technologies - Part 2
Hamidreza Soleimani
 
ProcessOne Push Platform: XMPP-based Push Solutions
ProcessOne Push Platform: XMPP-based Push SolutionsProcessOne Push Platform: XMPP-based Push Solutions
ProcessOne Push Platform: XMPP-based Push Solutions
Mickaël Rémond
 
Archipel Introduction - ejabberd SF Meetup
Archipel Introduction - ejabberd SF MeetupArchipel Introduction - ejabberd SF Meetup
Archipel Introduction - ejabberd SF Meetup
Mickaël Rémond
 
Multi Chat
Multi ChatMulti Chat
Multi Chat
SoftTeco
 
Nanomsg - Scalable Networking Library
Nanomsg - Scalable Networking LibraryNanomsg - Scalable Networking Library
Nanomsg - Scalable Networking Library
Hamidreza Soleimani
 
Real time Web Application with XMPP and Wave
Real time Web Application with XMPP and WaveReal time Web Application with XMPP and Wave
Real time Web Application with XMPP and Wave
Mickaël Rémond
 
2015: L'année d'Elixir, Code, écosystème et communauté
2015: L'année d'Elixir, Code, écosystème et communauté2015: L'année d'Elixir, Code, écosystème et communauté
2015: L'année d'Elixir, Code, écosystème et communauté
Mickaël Rémond
 
OneTeam Media Server
OneTeam Media ServerOneTeam Media Server
OneTeam Media Server
Mickaël Rémond
 
WaveOne server and client by ProcessOne
WaveOne server and client by ProcessOneWaveOne server and client by ProcessOne
WaveOne server and client by ProcessOne
Mickaël Rémond
 
Erlang White Label
Erlang White LabelErlang White Label
Erlang White Label
Mickaël Rémond
 
Real life XMPP Instant Messaging
Real life XMPP Instant MessagingReal life XMPP Instant Messaging
Real life XMPP Instant Messaging
Mickaël Rémond
 
Multitasking in iOS 7
Multitasking in iOS 7Multitasking in iOS 7
Multitasking in iOS 7
Mickaël Rémond
 
XMPP Academy #1
XMPP Academy #1XMPP Academy #1
XMPP Academy #1
Mickaël Rémond
 
Nodejs Applications in Production
Nodejs Applications in ProductionNodejs Applications in Production
Nodejs Applications in Production
Hamidreza Soleimani
 
Event Driven Architecture Concepts in Web Technologies - Part 1
Event Driven Architecture Concepts in Web Technologies - Part 1Event Driven Architecture Concepts in Web Technologies - Part 1
Event Driven Architecture Concepts in Web Technologies - Part 1
Hamidreza Soleimani
 

En vedette (20)

IoT Studio #1: Protocols introduction and connected jukebox
IoT Studio #1: Protocols introduction and connected jukeboxIoT Studio #1: Protocols introduction and connected jukebox
IoT Studio #1: Protocols introduction and connected jukebox
 
XMPP Academy #3
XMPP Academy #3XMPP Academy #3
XMPP Academy #3
 
Deep Dive Into ejabberd Pubsub Implementation
Deep Dive Into ejabberd Pubsub ImplementationDeep Dive Into ejabberd Pubsub Implementation
Deep Dive Into ejabberd Pubsub Implementation
 
Managing ejabberd Platforms with Docker - ejabberd Workshop #1
Managing ejabberd Platforms with Docker - ejabberd Workshop #1Managing ejabberd Platforms with Docker - ejabberd Workshop #1
Managing ejabberd Platforms with Docker - ejabberd Workshop #1
 
Create Your Own Language
Create Your Own LanguageCreate Your Own Language
Create Your Own Language
 
Event Driven Architecture Concepts in Web Technologies - Part 2
Event Driven Architecture Concepts in Web Technologies - Part 2Event Driven Architecture Concepts in Web Technologies - Part 2
Event Driven Architecture Concepts in Web Technologies - Part 2
 
ProcessOne Push Platform: XMPP-based Push Solutions
ProcessOne Push Platform: XMPP-based Push SolutionsProcessOne Push Platform: XMPP-based Push Solutions
ProcessOne Push Platform: XMPP-based Push Solutions
 
Archipel Introduction - ejabberd SF Meetup
Archipel Introduction - ejabberd SF MeetupArchipel Introduction - ejabberd SF Meetup
Archipel Introduction - ejabberd SF Meetup
 
Multi Chat
Multi ChatMulti Chat
Multi Chat
 
Nanomsg - Scalable Networking Library
Nanomsg - Scalable Networking LibraryNanomsg - Scalable Networking Library
Nanomsg - Scalable Networking Library
 
Real time Web Application with XMPP and Wave
Real time Web Application with XMPP and WaveReal time Web Application with XMPP and Wave
Real time Web Application with XMPP and Wave
 
2015: L'année d'Elixir, Code, écosystème et communauté
2015: L'année d'Elixir, Code, écosystème et communauté2015: L'année d'Elixir, Code, écosystème et communauté
2015: L'année d'Elixir, Code, écosystème et communauté
 
OneTeam Media Server
OneTeam Media ServerOneTeam Media Server
OneTeam Media Server
 
WaveOne server and client by ProcessOne
WaveOne server and client by ProcessOneWaveOne server and client by ProcessOne
WaveOne server and client by ProcessOne
 
Erlang White Label
Erlang White LabelErlang White Label
Erlang White Label
 
Real life XMPP Instant Messaging
Real life XMPP Instant MessagingReal life XMPP Instant Messaging
Real life XMPP Instant Messaging
 
Multitasking in iOS 7
Multitasking in iOS 7Multitasking in iOS 7
Multitasking in iOS 7
 
XMPP Academy #1
XMPP Academy #1XMPP Academy #1
XMPP Academy #1
 
Nodejs Applications in Production
Nodejs Applications in ProductionNodejs Applications in Production
Nodejs Applications in Production
 
Event Driven Architecture Concepts in Web Technologies - Part 1
Event Driven Architecture Concepts in Web Technologies - Part 1Event Driven Architecture Concepts in Web Technologies - Part 1
Event Driven Architecture Concepts in Web Technologies - Part 1
 

Similaire à Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8

Mieux Développer en PHP avec Symfony
Mieux Développer en PHP avec SymfonyMieux Développer en PHP avec Symfony
Mieux Développer en PHP avec Symfony
Hugo Hamon
 
Build automatique et distribution OTA avec Xcode 4.x et Jenkins
Build automatique et distribution OTA avec Xcode 4.x et JenkinsBuild automatique et distribution OTA avec Xcode 4.x et Jenkins
Build automatique et distribution OTA avec Xcode 4.x et Jenkins
CocoaHeads France
 
Test flight et les outils de distribution continue par simone civetta de xebia
Test flight et les outils de distribution continue par simone civetta de xebiaTest flight et les outils de distribution continue par simone civetta de xebia
Test flight et les outils de distribution continue par simone civetta de xebiaCocoaHeads France
 
Orchestrating Docker in production - TIAD Camp Docker
Orchestrating Docker in production - TIAD Camp DockerOrchestrating Docker in production - TIAD Camp Docker
Orchestrating Docker in production - TIAD Camp Docker
The Incredible Automation Day
 
Flex, une techno RIA incontournable pour les futures app web ?
Flex, une techno RIA incontournable pour les futures app web ?Flex, une techno RIA incontournable pour les futures app web ?
Flex, une techno RIA incontournable pour les futures app web ?
GreenIvory
 
Compte rendu Blend Web Mix 2015
Compte rendu Blend Web Mix 2015Compte rendu Blend Web Mix 2015
Compte rendu Blend Web Mix 2015
SQLI DIGITAL EXPERIENCE
 
Rich Desktop Applications
Rich Desktop ApplicationsRich Desktop Applications
Rich Desktop Applicationsgoldoraf
 
Presentation Symfony2
Presentation Symfony2Presentation Symfony2
Presentation Symfony2Ahmed ABATAL
 
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...
Publicis Sapient Engineering
 
20120110 paris jug-packaging-natif
20120110 paris jug-packaging-natif20120110 paris jug-packaging-natif
20120110 paris jug-packaging-natif
Henri Gomez
 
Silverlight 4
Silverlight 4Silverlight 4
Silverlight 4
Frédéric Queudret
 
Apache flink - prise en main rapide
Apache flink - prise en main rapideApache flink - prise en main rapide
Apache flink - prise en main rapide
Bilal Baltagi
 
Symfony 2 : chapitre 1 - Présentation Générale
Symfony 2 : chapitre 1 - Présentation GénéraleSymfony 2 : chapitre 1 - Présentation Générale
Symfony 2 : chapitre 1 - Présentation Générale
Abdelkader Rhouati
 
Être productif avec JHipster - Devoxx France 2017
Être productif avec JHipster - Devoxx France 2017Être productif avec JHipster - Devoxx France 2017
Être productif avec JHipster - Devoxx France 2017
Julien Dubois
 
What's Next Replay! Lyon 2011 - A. Cogoluegnes
What's Next Replay! Lyon 2011 - A. CogoluegnesWhat's Next Replay! Lyon 2011 - A. Cogoluegnes
What's Next Replay! Lyon 2011 - A. Cogoluegnes
Zenika
 
20111220 lyon jug-packaging-natif
20111220 lyon jug-packaging-natif20111220 lyon jug-packaging-natif
20111220 lyon jug-packaging-natif
Henri Gomez
 
Une visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs Web
Une visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs WebUne visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs Web
Une visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs Web
Frédéric Harper
 
Activity
ActivityActivity
Activitydido
 
Ops@viadeo : Puppet & Co... 6 mois après par Xavier Krantz
Ops@viadeo : Puppet & Co... 6 mois après par Xavier KrantzOps@viadeo : Puppet & Co... 6 mois après par Xavier Krantz
Ops@viadeo : Puppet & Co... 6 mois après par Xavier Krantz
Olivier DASINI
 

Similaire à Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8 (20)

Mieux Développer en PHP avec Symfony
Mieux Développer en PHP avec SymfonyMieux Développer en PHP avec Symfony
Mieux Développer en PHP avec Symfony
 
Build automatique et distribution OTA avec Xcode 4.x et Jenkins
Build automatique et distribution OTA avec Xcode 4.x et JenkinsBuild automatique et distribution OTA avec Xcode 4.x et Jenkins
Build automatique et distribution OTA avec Xcode 4.x et Jenkins
 
Test flight et les outils de distribution continue par simone civetta de xebia
Test flight et les outils de distribution continue par simone civetta de xebiaTest flight et les outils de distribution continue par simone civetta de xebia
Test flight et les outils de distribution continue par simone civetta de xebia
 
Orchestrating Docker in production - TIAD Camp Docker
Orchestrating Docker in production - TIAD Camp DockerOrchestrating Docker in production - TIAD Camp Docker
Orchestrating Docker in production - TIAD Camp Docker
 
Flex, une techno RIA incontournable pour les futures app web ?
Flex, une techno RIA incontournable pour les futures app web ?Flex, une techno RIA incontournable pour les futures app web ?
Flex, une techno RIA incontournable pour les futures app web ?
 
Compte rendu Blend Web Mix 2015
Compte rendu Blend Web Mix 2015Compte rendu Blend Web Mix 2015
Compte rendu Blend Web Mix 2015
 
Rich Desktop Applications
Rich Desktop ApplicationsRich Desktop Applications
Rich Desktop Applications
 
Presentation Symfony2
Presentation Symfony2Presentation Symfony2
Presentation Symfony2
 
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...
 
20120110 paris jug-packaging-natif
20120110 paris jug-packaging-natif20120110 paris jug-packaging-natif
20120110 paris jug-packaging-natif
 
Silverlight 4
Silverlight 4Silverlight 4
Silverlight 4
 
Apache flink - prise en main rapide
Apache flink - prise en main rapideApache flink - prise en main rapide
Apache flink - prise en main rapide
 
Symfony 2 : chapitre 1 - Présentation Générale
Symfony 2 : chapitre 1 - Présentation GénéraleSymfony 2 : chapitre 1 - Présentation Générale
Symfony 2 : chapitre 1 - Présentation Générale
 
Être productif avec JHipster - Devoxx France 2017
Être productif avec JHipster - Devoxx France 2017Être productif avec JHipster - Devoxx France 2017
Être productif avec JHipster - Devoxx France 2017
 
What's Next Replay! Lyon 2011 - A. Cogoluegnes
What's Next Replay! Lyon 2011 - A. CogoluegnesWhat's Next Replay! Lyon 2011 - A. Cogoluegnes
What's Next Replay! Lyon 2011 - A. Cogoluegnes
 
20111220 lyon jug-packaging-natif
20111220 lyon jug-packaging-natif20111220 lyon jug-packaging-natif
20111220 lyon jug-packaging-natif
 
Une visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs Web
Une visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs WebUne visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs Web
Une visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs Web
 
Starter Kits
Starter KitsStarter Kits
Starter Kits
 
Activity
ActivityActivity
Activity
 
Ops@viadeo : Puppet & Co... 6 mois après par Xavier Krantz
Ops@viadeo : Puppet & Co... 6 mois après par Xavier KrantzOps@viadeo : Puppet & Co... 6 mois après par Xavier Krantz
Ops@viadeo : Puppet & Co... 6 mois après par Xavier Krantz
 

Plus de Mickaël Rémond

Go for Real Time Streaming Architectures - DotGo 2017
Go for Real Time Streaming Architectures - DotGo 2017Go for Real Time Streaming Architectures - DotGo 2017
Go for Real Time Streaming Architectures - DotGo 2017
Mickaël Rémond
 
Fighting XMPP abuse and spam with ejabberd - ejabberd Workshop #1
Fighting XMPP abuse and spam with ejabberd - ejabberd Workshop #1Fighting XMPP abuse and spam with ejabberd - ejabberd Workshop #1
Fighting XMPP abuse and spam with ejabberd - ejabberd Workshop #1
Mickaël Rémond
 
Messaging temps réel avec Go
Messaging temps réel avec GoMessaging temps réel avec Go
Messaging temps réel avec Go
Mickaël Rémond
 
Building Scalable Systems: What you can learn from Erlang - DotScale 2016
Building Scalable Systems: What you can learn from Erlang - DotScale 2016Building Scalable Systems: What you can learn from Erlang - DotScale 2016
Building Scalable Systems: What you can learn from Erlang - DotScale 2016
Mickaël Rémond
 
Property-based testing of XMPP: generate your tests automatically - ejabberd ...
Property-based testing of XMPP: generate your tests automatically - ejabberd ...Property-based testing of XMPP: generate your tests automatically - ejabberd ...
Property-based testing of XMPP: generate your tests automatically - ejabberd ...
Mickaël Rémond
 
XMPP Academy #2
XMPP Academy #2XMPP Academy #2
XMPP Academy #2
Mickaël Rémond
 
A vision for ejabberd - ejabberd SF Meetup
A vision for ejabberd - ejabberd SF MeetupA vision for ejabberd - ejabberd SF Meetup
A vision for ejabberd - ejabberd SF Meetup
Mickaël Rémond
 
OneTeam Media Server
OneTeam Media ServerOneTeam Media Server
OneTeam Media Server
Mickaël Rémond
 

Plus de Mickaël Rémond (8)

Go for Real Time Streaming Architectures - DotGo 2017
Go for Real Time Streaming Architectures - DotGo 2017Go for Real Time Streaming Architectures - DotGo 2017
Go for Real Time Streaming Architectures - DotGo 2017
 
Fighting XMPP abuse and spam with ejabberd - ejabberd Workshop #1
Fighting XMPP abuse and spam with ejabberd - ejabberd Workshop #1Fighting XMPP abuse and spam with ejabberd - ejabberd Workshop #1
Fighting XMPP abuse and spam with ejabberd - ejabberd Workshop #1
 
Messaging temps réel avec Go
Messaging temps réel avec GoMessaging temps réel avec Go
Messaging temps réel avec Go
 
Building Scalable Systems: What you can learn from Erlang - DotScale 2016
Building Scalable Systems: What you can learn from Erlang - DotScale 2016Building Scalable Systems: What you can learn from Erlang - DotScale 2016
Building Scalable Systems: What you can learn from Erlang - DotScale 2016
 
Property-based testing of XMPP: generate your tests automatically - ejabberd ...
Property-based testing of XMPP: generate your tests automatically - ejabberd ...Property-based testing of XMPP: generate your tests automatically - ejabberd ...
Property-based testing of XMPP: generate your tests automatically - ejabberd ...
 
XMPP Academy #2
XMPP Academy #2XMPP Academy #2
XMPP Academy #2
 
A vision for ejabberd - ejabberd SF Meetup
A vision for ejabberd - ejabberd SF MeetupA vision for ejabberd - ejabberd SF Meetup
A vision for ejabberd - ejabberd SF Meetup
 
OneTeam Media Server
OneTeam Media ServerOneTeam Media Server
OneTeam Media Server
 

Dernier

Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)
Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)
Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)
Laurent Speyser
 
OCTO TALKS : 4 Tech Trends du Software Engineering.pdf
OCTO TALKS : 4 Tech Trends du Software Engineering.pdfOCTO TALKS : 4 Tech Trends du Software Engineering.pdf
OCTO TALKS : 4 Tech Trends du Software Engineering.pdf
OCTO Technology
 
De l'IA comme plagiat à la rédaction d'une « charte IA » à l'université
De l'IA comme plagiat à la rédaction d'une « charte IA » à l'universitéDe l'IA comme plagiat à la rédaction d'une « charte IA » à l'université
De l'IA comme plagiat à la rédaction d'une « charte IA » à l'université
Université de Franche-Comté
 
Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...
Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...
Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...
OCTO Technology
 
Le support de présentation des Signaux 2024
Le support de présentation des Signaux 2024Le support de présentation des Signaux 2024
Le support de présentation des Signaux 2024
UNITECBordeaux
 
Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...
Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...
Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...
OCTO Technology
 

Dernier (6)

Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)
Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)
Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)
 
OCTO TALKS : 4 Tech Trends du Software Engineering.pdf
OCTO TALKS : 4 Tech Trends du Software Engineering.pdfOCTO TALKS : 4 Tech Trends du Software Engineering.pdf
OCTO TALKS : 4 Tech Trends du Software Engineering.pdf
 
De l'IA comme plagiat à la rédaction d'une « charte IA » à l'université
De l'IA comme plagiat à la rédaction d'une « charte IA » à l'universitéDe l'IA comme plagiat à la rédaction d'une « charte IA » à l'université
De l'IA comme plagiat à la rédaction d'une « charte IA » à l'université
 
Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...
Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...
Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...
 
Le support de présentation des Signaux 2024
Le support de présentation des Signaux 2024Le support de présentation des Signaux 2024
Le support de présentation des Signaux 2024
 
Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...
Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...
Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...
 

Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8

  • 1. Phoenix Presence: Le service temps réel de Phoenix 1.2 Mickaël Rémond ProcessOne
  • 3. Qu'est-ce que Phoenix ? Framework de développement Web Développement lancé en août 2014 avec un focus sur les websockets Inspiration venant de différents frameworks: Ruby on Rails, Clojure Ring, Scala Playframework, ... Version 1.0 sortie en août 2015. Version 1.1 en décembre 2015. Version 1.2 majeure en juin 2016.
  • 4. Les atouts de Phoenix Points forts: Élégance grâce à la syntaxe d'Elixir et à son système de macros (DSL) Performance et clustering grâce à la VM Erlang Productivité avec des outils de base de données comme Ecto Fonctionnalités: couvre le support des pages web dynamiques. interactions temps réel: websockets et presence.
  • 5. De Phoenix 1.0 à Phoenix 1.2 Phoenix 1.1: Amélioration des performances des channels Localisation via Gettext Phoenix 1.2: Ecto 2.0 Phoenix Presence
  • 6. Références Introduction au développement Web avec le framework Phoenix www.youtube.com/watch?v=GPF6w3CsWio(https://www.youtube.com/watch?v=GPF6w3CsWio) Site Web de Phoenix www.phoenixframework.org(http://www.phoenixframework.org)
  • 8. Définitions Websockets: protocole de communication entre le navigateur et le serveur. Maintiens la connexion pendant la durée de la session. Channels: Les channels définisset le comportement du serveur pour le broadcast de message en temps réel, par "sujet" (topic). Presence: Le module de "présence tracker synchronize l'état des joins et des leaves de sur les topics, via le module channel, et broadcast les changements.
  • 10. Presence vs Channels ? La fonctionnalité de Phoenix Presence vient sous la forme d'un presence tracker. Il s'agit d'une structure de données en mémoire, répliquée et synchronisée en temps réel sur tous les noeuds d'un cluster Elixir. Elle s'appuie sur les channels: pour recevoir les événements de join et de leave. pour envoyer l'état initial et les mises à jour incrémentales. Phoenix Presence permet: la découverte de service / composants du système. la gestion de la présence des utilisateurs.
  • 11. Points forts de Phoenix Presence Robustesse: Réplication en temps réel sur l'ensemble du cluster. pas de point de failure unique (SPOF). peut continuer à fonctionner lors d'un netsplit. supporte de fortes charges. Simplicité: de gestion: gère la réconciliation automatiquement lorsque le cluster se reconstitue. de déploiement: dépends uniquement de module standard, sans dépendance externe. d'implémentation: est fourni avec un module Javascript pour faciliter l'implémentation des clients.
  • 12. Limitations Phoenix Presence est une structure de données distribuée. Les fonctionnalités restent d'assez bas niveau. Il est idéal pour gérer la présence en temps réel pour des communautés: Site web Jeu vidéo Il reste un système simple, fonctionnant sur la base de topic et de channels: Pas de liste de contacts / présence individuelle.
  • 14. L'exemple Gastronokids Application d'illustration utilisée dans ma précédente présentation sur Phoenix. github.com/ElixirParis/gastronokids(https://github.com/ElixirParis/gastronokids) Enrichissement pour ajouter un module de présence.
  • 15. Étape 1: Mise à jour de Phoenix 1.0 à Phoenix 1.2
  • 16. Changements Résumé: Migration vers Postgres: SQLite Ecto ne fonctionne pas encore avec Ecto 2.0 Mise à jour des dépendances Elixir et Javascript Mise à jour vers Ecto 2.0: Model -> Schema Ajout du support de la localisation Gettext Changement du code de gestion des erreurs dans les formulaires Commit complet: Github: Migrate for Phoenix 1.0 to Phoenix 1.2 + move to Postgres (https://github.com/ElixirParis/gastronokids/commit/418e10926c7e647b47628d2006a91123496a57da)
  • 17. Étape 2: Ajout du module de présence
  • 18. Générer le code du module Presence Utilisation du scaffolding pour générer le code: $ mix phoenix.gen.presence * creating web/channels/presence.ex Add your new module to your supervision tree, in lib/gastronokids.ex: children = [ ... supervisor(Gastronokids.Presence, []), ] You're all set! See the Phoenix.Presence docs for more details: http://hexdocs.pm/phoenix/Phoenix.Presence.html Nous utilisons le module en l'état.
  • 20. Ajouter le service de présence dans l'application Dans lib/gastronokids.ex, ajout du module dans l'arbre de supervision: def start(_type, _args) do import Supervisor.Spec, warn: false children = [ # Start the endpoint when the application starts supervisor(Gastronokids.Endpoint, []), # Start the Ecto repository worker(Gastronokids.Repo, []), # Presence tracker: supervisor(Gastronokids.Presence, []), ] # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html # for other strategies and supported options opts = [strategy: :one_for_one, name: Gastronokids.Supervisor] Supervisor.start_link(children, opts) end
  • 21. Config PubSub Vérifier que le service PubSub est bien configuré dans config/config.exs: config :gastronokids, Gastronokids.Endpoint, url: [host: "localhost"], secret_key_base: "j458rtSt4qQnUmBDEVmjX3X6tCtLLjWJy6rhO58WO86s1S2I3i4zePgdcV/T3N41", render_errors: [view: Gastronokids.ErrorView, accepts: ~w(html json)], # This is mapping between name and pubsub backend pubsub: [name: Gastronokids.PubSub, adapter: Phoenix.PubSub.PG2]
  • 23. Lier la présence aux channels (1/2) Importer notre module de présence dans web/channel/room_channel.ex: defmodule Gastronokids.RoomChannel do use Gastronokids.Web, :channel alias Gastronokids.Presence Déclencher un événement de join asynchrone: def join("rooms:lobby", payload, socket) do if authorized?(payload) do send self(), :after_join {:ok, socket} else {:error, %{reason: "unauthorized"}} end end
  • 24. Lier la présence aux channels (2/2) Garder la trace de la présence après le join et broadcast de la liste initiale: def handle_info(:after_join, socket) do Presence.track(socket, socket.assigns.user_id, %{ device: "browser", online_at: inspect(:os.timestamp()) }) push socket, "presence_state", Presence.list(socket) {:noreply, socket} end Note: Il n'est pas nécessaire de gérer la déconnexion / leave. Channels et Presence gèrent cela pour le développeur.
  • 25. Broadcast des messages de chat Le callback handle_in sert toujours à assurer la diffusion des messages de chat: def handle_in("new_msg", payload, socket) do payloadWithUser = %{"body" => payload["body"], "user": socket.assigns.user_id} broadcast! socket, "new_msg", payloadWithUser {:noreply, socket} end Le callback handle_out n'est pas nécessaire, car nous utilisons l'implémentation par défaut.
  • 27. Assigner le user_id à la socket Nous étendons la fonction connect/2 dans web/channels/user_socket.ex: def connect(%{"user_id" => id}, socket) do {:ok, assign(socket, :user_id, id)} end
  • 28. Le client Javascript socket.js
  • 29. Mise en place socket / présence Dans web/static/js/socket.js, nous importons Socket et Presence, et créons une nouvelle socket: import {Socket, Presence} from "phoenix" let socket = new Socket("/socket", {params: {token: window.userToken, user_id: window.userId}}) Nous lançons la connexion et initialons l'environnement: socket.connect() let channel = socket.channel("rooms:lobby", {}) let presences = {}
  • 30. Gestion des événements de présence La lib Phoenix Presence Javascript gère l'état des présences pour le développeur: channel.on("presence_state", state => { presences = Presence.syncState(presences, state) render(presences) }) channel.on("presence_diff", diff => { presences = Presence.syncDiff(presences, diff) render(presences) })
  • 31. Afficher la liste de présence La lib Phoenix Presence Javascript permet de récupérer et trier la liste des présences: let listBy = (id, {metas: [first, ...rest]}) => { first.name = id first.count = rest.length +1 return first } let render = (presences) => { let onlineUsers = Presence.list(presences, listBy) let htmlList = onlineUsers .map(user => `<li>${user.name} (${user.count})</li>`) .join("") userList.html(htmlList) }
  • 32. Gestion des messages Pour finir, nous gérer la réception et l'envoi des messages: channel.on("new_msg", payload => { var now = new Date(); messagesContainer.append(`<br/>[${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}] ${payload.use }) chatInput.on("keypress", event => { if(event.keyCode === 13){ channel.push("new_msg", {body: chatInput.val()}) chatInput.val("") } })
  • 34. Mise en place du code HTML Notre code fournit des éléments conteneurs pour les utilisateurs présents et le chat: <p>Online Users:</p> <ul id="user-list"></ul> <div class="chat"> <div id="messages"></div> <input id="chat-input" type="text"></input> </div> Pour simplifier, le nom de l'utilisateur vient des paramètres de la page: <script> window.userId = "<%= if @conn.params["name"], do: @conn.params["name"], else: "Anonymous" %>" </script>
  • 36. Télécharger le code Github Gastronokids github.com/ElixirParis/gastronokids(https://github.com/ElixirParis/gastronokids)
  • 37. Conclusion L'ajout du module de Presence complète les channels de Phoenix de manière redoutablement efficace. Avec cet ajout, Phoenix devient l'outil le plus complet pour implémenter des applications web temps réel reliant: Base de données. Système de templating de pages. Mise à jour temps réel via un outillage Javascript complet. Et tout cela, dans un package unique, sans dépendance.