Messaging temps réel avec Go
Mickaël Rémond
ProcessOne
Retour d'expérience
Construction d'objets connectés en Go
Introduction: Pourquoi utiliser Go pour le
messaging ?
Pertinence
Go est pertinent pour le messaging temps réel:
sur le client: objets connectés
sur le serveur: plate-forme de messaging
Pour les clients / objets connectés
Channels: Le passage de messages est au coeur du language Go.
Cross compilation: Il est possible de compiler et déployer le code client sur une
architecture différente.
Accès système: La création d'objet est simplifiée par les capacités systèmes de Go.
Pour les serveurs
Performant sur deux axes:
Go routines: Connections simultanés
Les serveurs de messagerie gèrent de nombreux processus en parallèle
Performance: Débit
Permet de développer des systèmes ayant un fort débit en terme de nombre de
messages par seconde.
Latence:
Permet de réduire fortement la latence dans la transmission des messages.
Exemple: NATS
gnatsd, implementation du protocole Nats.io
NATS: Capacité de traitement
Source: Brave New Geek
NATS: Latence
Source: Brave New Geek
Illustration du messaging avec divers protocoles
À connaître:
XMPP: eXtensible Messaging and Presence Protocol
xmpp.org(http://xmpp.org)
MQTT: Message Queuing Telemetry Transport
mqtt.org(http://mqtt.org)
NATS: Protocole et serveur
nats.io(http://nats.io)
Cette présentation se concentre sur l'utilisation des serveurs de messaging depuis un
client Go.
La mise en œuvre de serveurs de messaging en pur Go viendra dans une autre
présentation.
Code
XMPP
XMPP est idéal pour le contrôle des objets.
Le protocole est extensible et propose des spécifications adaptées à l'écriture de
séquences d'interaction pour le contrôle:
Découverte (XEP-0347: Internet of Things - Discovery)
Contrôle: Requête / Réponse (XEP-0325: Internet of Things - Control)
Développement d'un Jukebox XMPP en Go
Technologies utilisées:
Protocole XMPP
ejabberd: serveur XMPP
Bibliothèque XMPP en Go, Gox: écriture du Jukebox
Raspberry Pi 2 avec image Linux custom et haut parleur connecté à la sortie son
analogique
Connexion à SoundCloud
Architecture
Contrôle XMPP du jukebox: Chat bot
Le jukebox joue les liens Soundcloud envoyés dans le chat:
<message type="chat" to="test@localhost" id="aac9a">
<body>https://soundcloud.com/radiohead/spectre</body>
</message>
Il stoppe la musique en cours de lecture avec la commande stop:
<message type="chat" to="test@localhost" id="aacaa">
<body>stop</body>
</message>
Contrôle du jukebox: IoT XMPP Control
Notre jukebox peut interpréter les requêtes de commande IoT (XEP-0325):
<iq type='set'
    to='test@localhost/jukebox'
    id='2'>
   <set xmlns='urn:xmpp:iot:control' xml:lang='en'>
     <string name='action' value='play'/>
     <string name='url' value='https://soundcloud.com/radiohead/spectre'/>
   </set>
</iq>
Code du jukebox: Main receive loop
Déclaration de la connection XMPP:
var client *xmpp.Client
var err error
if client, err = connectXmpp(*jid, *password, *address); err != nil {
log.Fatal("Could not connect to XMPP: ", err)
}
Boucle de traitement des paquets XMPP:
for packet := range client.Recv() {
switch packet := packet.(type) {
case *xmpp.ClientMessage:
processMessage(client, p, packet)
case *xmpp.ClientIQ:
processIq(client, p, packet)
case *xmpp.ClientPresence:
// Do nothing with received presence
default:
fmt.Printf("Ignoring packet: %Tn", packet)
}
}
Code du jukebox: Connexion XMPP
func connectXmpp(jid string, password string, address string) (client *xmpp.Client, err error) {
xmppOptions := xmpp.Options{Address: address,
Jid: jid, Password: password, PacketLogger: os.Stdout,
Retry: 10}
if client, err = xmpp.NewClient(xmppOptions); err != nil {
return
}
if _, err = client.Connect(); err != nil {
return
}
return
}
Traitement des messsages
func processMessage(client *xmpp.Client, p *mpg123.Player, packet *xmpp.ClientMessage) {
command := strings.Trim(packet.Body, " ")
if command == "stop" {
p.Stop()
} else {
playSCURL(p, command)
}
}
Traitement des commandes
func processIq(client *xmpp.Client, p *mpg123.Player, packet *xmpp.ClientIQ) {
switch payload := packet.Payload.(type) {
// We support IOT Control IQ
case *iot.ControlSet:
var url string
for _, element := range payload.Fields {
if element.XMLName.Local == "string" && element.Name == "url" {
url = strings.Trim(element.Value, " ")
break
}
}
playSCURL(p, url)
setResponse := new(iot.ControlSetResponse)
reply := xmpp.ClientIQ{Packet: xmpp.Packet{To: packet.From, Type: "result", Id: packet.Id}, Pay
client.Send(reply.XMPPFormat())
default:
fmt.Printf("Other IQ Payload: %Tn", packet.Payload)
}
}
Jouer le morceau SoundCloud
func playSCURL(p *mpg123.Player, rawURL string) {
songID, _ := soundcloud.GetSongID(rawURL)
url := soundcloud.FormatStreamURL(songID)
p.Play(url)
}
MQTT
MQTT est idéal pour remonter l'information venant de capteurs.
Reporting d'un capteur de température
Technologies utilisées:
Capteur: Températeur CPU OSX
sysctl -n machdep.xcpm.cpu_thermal_level
Serveur MQTT de test: Mosquitto
Bibliothèque MQTT en Go: ProcessOne MQTT
Publisher: Mise en place de la connexion
func main() {
client := mqtt.New("localhost:1883", nil)
client.ClientID = "mremond-osx"
if err := client.Connect(); err != nil {
log.Fatal("Connection error: ", err)
}
ticker := time.NewTicker(5 * time.Second)
stop := make(chan bool)
go publishLoop(client, ticker, stop)
runtime.Goexit()
}
Publisher: La boucle de publication
func publishLoop(client *mqtt.Client, ticker *time.Ticker, stop <-chan bool) {
for done := false; !done; {
select {
case <-ticker.C:
payload := make([]byte, 1, 1)
payload[0] = getTemp()
client.Publish(getTopic(client.ClientID), payload)
case <-stop:
done = true
break
}
}
}
Publisher: La lecture de la température
func getTemp() byte {
out, err := exec.Command("sysctl", "-n", "machdep.xcpm.cpu_thermal_level").Output()
if err != nil {
log.Println("Cannot read CPU temperature: ", err)
return byte(0)
}
s := string(out)
if temp, err := strconv.ParseInt(strings.Trim(s, "n"), 10, 32); err != nil {
return byte(temp)
}
return byte(0)
}
Subscriber
func main() {
messages := make(chan *mqtt.Message)
client := mqtt.New("localhost:1883", messages)
client.ClientID = "MQTT-Sub"
if err := client.Connect(); err != nil {
fmt.Printf("Connection error: %qn", err)
return
}
name := "mremond-osx/cputemp"
topic := packet.Topic{Name: name, QOS: 1}
client.Subscribe(topic)
for m := range messages {
fmt.Printf("Received message on topic %s: %+vn", m.Topic, m.Payload)
}
}
Prochaines étapes
Publication du code client MQTT:
Publication pour la fin de semaine, après nettoyage et documentation, sur le
compte Github de ProcessOne(https://github.com/processone/)
Présentation de ce que j'ai appris lors du design de l'API de la bibliothèque ?
Mise en oeuvre de serveurs de messaging en Go:
Présentation du serveur NATS ?: Illustration de NATS qui est un protocol non
standard mais également très performant.
Autres serveurs de messaging en Go.
Liens
Code des slides
github.com/processone/talks/tree/master/2016/go-paris-meetup
(https://github.com/processone/talks/tree/master/2016/go-paris-meetup)
Go XMPP
github.com/processone/gox(https://github.com/processone/gox)
Go MQTT
github.com/processone/mqtt(https://github.com/processone/mqtt)
Brave New Geek: Dissecting Message Queues
bravenewgeek.com/dissecting-message-queues/(http://bravenewgeek.com/dissecting-message-queues/)
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)
Messaging temps réel avec Go

Contenu connexe

PPT
APACHE TOMCAT
PDF
Apache Kafka, Un système distribué de messagerie hautement performant
PDF
Kafka Connect & Kafka Streams - Paris Kafka User Group
PDF
Python + ansible = ♥
PDF
Paris Kafka Meetup - Concepts & Architecture
PPTX
Windows server2016 presentation
PDF
Dhcp3
PDF
AMQP: interopérabilité et découplage de systèmes hétérogènes avec RabbitMQ
APACHE TOMCAT
Apache Kafka, Un système distribué de messagerie hautement performant
Kafka Connect & Kafka Streams - Paris Kafka User Group
Python + ansible = ♥
Paris Kafka Meetup - Concepts & Architecture
Windows server2016 presentation
Dhcp3
AMQP: interopérabilité et découplage de systèmes hétérogènes avec RabbitMQ

Tendances (18)

PDF
Présentation de Apache Zookeeper
PPTX
PPTX
Serveurs
PPTX
WebSocket avec Java EE 7
ODP
09 01 configuration du serveur samba
PPTX
PDF
Examen
PPT
APACHE HTTP
ODP
Etes vous prêts pour le succes ?
PDF
[2017년 5월 정기세미나] Network with OpenStack - OpenStack Summit Boston Post
PDF
Cours services web_fabrice_mourlin
PDF
Messages queues - Socloz@PHPForum 2013
PPTX
Présentation Microsoft Advanced Threat Analytics | Deep-Dive - MSCloud Summi...
PDF
FreeBSD vs Linux, RMLL 2014
PPT
3 switchport securité
PPTX
Drupal 8, symfony
PPTX
Création des sites web pour débutant
Présentation de Apache Zookeeper
Serveurs
WebSocket avec Java EE 7
09 01 configuration du serveur samba
Examen
APACHE HTTP
Etes vous prêts pour le succes ?
[2017년 5월 정기세미나] Network with OpenStack - OpenStack Summit Boston Post
Cours services web_fabrice_mourlin
Messages queues - Socloz@PHPForum 2013
Présentation Microsoft Advanced Threat Analytics | Deep-Dive - MSCloud Summi...
FreeBSD vs Linux, RMLL 2014
3 switchport securité
Drupal 8, symfony
Création des sites web pour débutant
Publicité

Similaire à Messaging temps réel avec Go (8)

PPTX
Projet MQTT
PDF
MQTT avec Mosquitto et Paho - DevFest Brest 2019
PDF
MQTT avec Mosquitto et Paho - Laurent Guerin - JUG Nantes Nov 2018
PDF
Parlez vous IoT - Présentation du protocole MQTT
PDF
IoT Toulouse : introduction à mqtt
PDF
Développement d'un client MQTT sur Raspberry Pi
PDF
8-socket.pdf
PDF
Développer un client MQTT simple en C++ avec la bibliothèque Paho MQTT
Projet MQTT
MQTT avec Mosquitto et Paho - DevFest Brest 2019
MQTT avec Mosquitto et Paho - Laurent Guerin - JUG Nantes Nov 2018
Parlez vous IoT - Présentation du protocole MQTT
IoT Toulouse : introduction à mqtt
Développement d'un client MQTT sur Raspberry Pi
8-socket.pdf
Développer un client MQTT simple en C++ avec la bibliothèque Paho MQTT
Publicité

Plus de Mickaël Rémond (20)

PDF
Go for Real Time Streaming Architectures - DotGo 2017
PDF
Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8
PDF
Fighting XMPP abuse and spam with ejabberd - ejabberd Workshop #1
PDF
Managing ejabberd Platforms with Docker - ejabberd Workshop #1
PDF
Building Scalable Systems: What you can learn from Erlang - DotScale 2016
PPTX
Property-based testing of XMPP: generate your tests automatically - ejabberd ...
PDF
IoT Studio #1: Protocols introduction and connected jukebox
PDF
Deep Dive Into ejabberd Pubsub Implementation
PDF
XMPP Academy #3
PPTX
XMPP Academy #2
PDF
2015: L'année d'Elixir, Code, écosystème et communauté
PDF
XMPP Academy #1
PDF
Archipel Introduction - ejabberd SF Meetup
PDF
A vision for ejabberd - ejabberd SF Meetup
PDF
Multitasking in iOS 7
ZIP
ProcessOne Push Platform: XMPP-based Push Solutions
ZIP
WaveOne server and client by ProcessOne
ZIP
Real time Web Application with XMPP and Wave
PDF
Erlang White Label
ZIP
OneTeam Media Server
Go for Real Time Streaming Architectures - DotGo 2017
Phoenix Presence: Le service temps réel de Phoenix - Paris.ex #8
Fighting XMPP abuse and spam with ejabberd - ejabberd Workshop #1
Managing ejabberd Platforms with Docker - ejabberd Workshop #1
Building Scalable Systems: What you can learn from Erlang - DotScale 2016
Property-based testing of XMPP: generate your tests automatically - ejabberd ...
IoT Studio #1: Protocols introduction and connected jukebox
Deep Dive Into ejabberd Pubsub Implementation
XMPP Academy #3
XMPP Academy #2
2015: L'année d'Elixir, Code, écosystème et communauté
XMPP Academy #1
Archipel Introduction - ejabberd SF Meetup
A vision for ejabberd - ejabberd SF Meetup
Multitasking in iOS 7
ProcessOne Push Platform: XMPP-based Push Solutions
WaveOne server and client by ProcessOne
Real time Web Application with XMPP and Wave
Erlang White Label
OneTeam Media Server

Dernier (9)

PDF
Gestion de la main-d’œuvre dans SAP Extended Warehouse Management, EWM125 Col26
PPTX
843555943-Introduction-a-l-Intelligence-Artificielle.pptx
PDF
1.3.4-Handling-and-Safety-Instructions-FR-2024.pdf
PDF
Cours du langage HTML depuis initiation à la maîtrise
PPTX
Pourquoi j'ai arrêté Magento : neuf ans de transitions technologiques
PDF
SHAKA 2025 - Création d'Images en IA : Mode Expert Activé
PDF
Utilisation de la gestion des ressources dans SAP Extended Warehouse Manageme...
PDF
Personnalisation de rubriques supplémentaires dans SAP Extended Warehouse Man...
PDF
Gestion des stocks et inventaire, SCM510 Col15
Gestion de la main-d’œuvre dans SAP Extended Warehouse Management, EWM125 Col26
843555943-Introduction-a-l-Intelligence-Artificielle.pptx
1.3.4-Handling-and-Safety-Instructions-FR-2024.pdf
Cours du langage HTML depuis initiation à la maîtrise
Pourquoi j'ai arrêté Magento : neuf ans de transitions technologiques
SHAKA 2025 - Création d'Images en IA : Mode Expert Activé
Utilisation de la gestion des ressources dans SAP Extended Warehouse Manageme...
Personnalisation de rubriques supplémentaires dans SAP Extended Warehouse Man...
Gestion des stocks et inventaire, SCM510 Col15

Messaging temps réel avec Go

  • 1. Messaging temps réel avec Go Mickaël Rémond ProcessOne
  • 3. Introduction: Pourquoi utiliser Go pour le messaging ?
  • 4. Pertinence Go est pertinent pour le messaging temps réel: sur le client: objets connectés sur le serveur: plate-forme de messaging
  • 5. Pour les clients / objets connectés Channels: Le passage de messages est au coeur du language Go. Cross compilation: Il est possible de compiler et déployer le code client sur une architecture différente. Accès système: La création d'objet est simplifiée par les capacités systèmes de Go.
  • 6. Pour les serveurs Performant sur deux axes: Go routines: Connections simultanés Les serveurs de messagerie gèrent de nombreux processus en parallèle Performance: Débit Permet de développer des systèmes ayant un fort débit en terme de nombre de messages par seconde. Latence: Permet de réduire fortement la latence dans la transmission des messages.
  • 8. NATS: Capacité de traitement Source: Brave New Geek
  • 10. Illustration du messaging avec divers protocoles À connaître: XMPP: eXtensible Messaging and Presence Protocol xmpp.org(http://xmpp.org) MQTT: Message Queuing Telemetry Transport mqtt.org(http://mqtt.org) NATS: Protocole et serveur nats.io(http://nats.io) Cette présentation se concentre sur l'utilisation des serveurs de messaging depuis un client Go. La mise en œuvre de serveurs de messaging en pur Go viendra dans une autre présentation.
  • 11. Code
  • 12. XMPP XMPP est idéal pour le contrôle des objets. Le protocole est extensible et propose des spécifications adaptées à l'écriture de séquences d'interaction pour le contrôle: Découverte (XEP-0347: Internet of Things - Discovery) Contrôle: Requête / Réponse (XEP-0325: Internet of Things - Control)
  • 13. Développement d'un Jukebox XMPP en Go Technologies utilisées: Protocole XMPP ejabberd: serveur XMPP Bibliothèque XMPP en Go, Gox: écriture du Jukebox Raspberry Pi 2 avec image Linux custom et haut parleur connecté à la sortie son analogique Connexion à SoundCloud
  • 15. Contrôle XMPP du jukebox: Chat bot Le jukebox joue les liens Soundcloud envoyés dans le chat: <message type="chat" to="test@localhost" id="aac9a"> <body>https://soundcloud.com/radiohead/spectre</body> </message> Il stoppe la musique en cours de lecture avec la commande stop: <message type="chat" to="test@localhost" id="aacaa"> <body>stop</body> </message>
  • 16. Contrôle du jukebox: IoT XMPP Control Notre jukebox peut interpréter les requêtes de commande IoT (XEP-0325): <iq type='set'     to='test@localhost/jukebox'     id='2'>    <set xmlns='urn:xmpp:iot:control' xml:lang='en'>      <string name='action' value='play'/>      <string name='url' value='https://soundcloud.com/radiohead/spectre'/>    </set> </iq>
  • 17. Code du jukebox: Main receive loop Déclaration de la connection XMPP: var client *xmpp.Client var err error if client, err = connectXmpp(*jid, *password, *address); err != nil { log.Fatal("Could not connect to XMPP: ", err) } Boucle de traitement des paquets XMPP: for packet := range client.Recv() { switch packet := packet.(type) { case *xmpp.ClientMessage: processMessage(client, p, packet) case *xmpp.ClientIQ: processIq(client, p, packet) case *xmpp.ClientPresence: // Do nothing with received presence default: fmt.Printf("Ignoring packet: %Tn", packet) } }
  • 18. Code du jukebox: Connexion XMPP func connectXmpp(jid string, password string, address string) (client *xmpp.Client, err error) { xmppOptions := xmpp.Options{Address: address, Jid: jid, Password: password, PacketLogger: os.Stdout, Retry: 10} if client, err = xmpp.NewClient(xmppOptions); err != nil { return } if _, err = client.Connect(); err != nil { return } return }
  • 19. Traitement des messsages func processMessage(client *xmpp.Client, p *mpg123.Player, packet *xmpp.ClientMessage) { command := strings.Trim(packet.Body, " ") if command == "stop" { p.Stop() } else { playSCURL(p, command) } }
  • 20. Traitement des commandes func processIq(client *xmpp.Client, p *mpg123.Player, packet *xmpp.ClientIQ) { switch payload := packet.Payload.(type) { // We support IOT Control IQ case *iot.ControlSet: var url string for _, element := range payload.Fields { if element.XMLName.Local == "string" && element.Name == "url" { url = strings.Trim(element.Value, " ") break } } playSCURL(p, url) setResponse := new(iot.ControlSetResponse) reply := xmpp.ClientIQ{Packet: xmpp.Packet{To: packet.From, Type: "result", Id: packet.Id}, Pay client.Send(reply.XMPPFormat()) default: fmt.Printf("Other IQ Payload: %Tn", packet.Payload) } }
  • 21. Jouer le morceau SoundCloud func playSCURL(p *mpg123.Player, rawURL string) { songID, _ := soundcloud.GetSongID(rawURL) url := soundcloud.FormatStreamURL(songID) p.Play(url) }
  • 22. MQTT MQTT est idéal pour remonter l'information venant de capteurs.
  • 23. Reporting d'un capteur de température Technologies utilisées: Capteur: Températeur CPU OSX sysctl -n machdep.xcpm.cpu_thermal_level Serveur MQTT de test: Mosquitto Bibliothèque MQTT en Go: ProcessOne MQTT
  • 24. Publisher: Mise en place de la connexion func main() { client := mqtt.New("localhost:1883", nil) client.ClientID = "mremond-osx" if err := client.Connect(); err != nil { log.Fatal("Connection error: ", err) } ticker := time.NewTicker(5 * time.Second) stop := make(chan bool) go publishLoop(client, ticker, stop) runtime.Goexit() }
  • 25. Publisher: La boucle de publication func publishLoop(client *mqtt.Client, ticker *time.Ticker, stop <-chan bool) { for done := false; !done; { select { case <-ticker.C: payload := make([]byte, 1, 1) payload[0] = getTemp() client.Publish(getTopic(client.ClientID), payload) case <-stop: done = true break } } }
  • 26. Publisher: La lecture de la température func getTemp() byte { out, err := exec.Command("sysctl", "-n", "machdep.xcpm.cpu_thermal_level").Output() if err != nil { log.Println("Cannot read CPU temperature: ", err) return byte(0) } s := string(out) if temp, err := strconv.ParseInt(strings.Trim(s, "n"), 10, 32); err != nil { return byte(temp) } return byte(0) }
  • 27. Subscriber func main() { messages := make(chan *mqtt.Message) client := mqtt.New("localhost:1883", messages) client.ClientID = "MQTT-Sub" if err := client.Connect(); err != nil { fmt.Printf("Connection error: %qn", err) return } name := "mremond-osx/cputemp" topic := packet.Topic{Name: name, QOS: 1} client.Subscribe(topic) for m := range messages { fmt.Printf("Received message on topic %s: %+vn", m.Topic, m.Payload) } }
  • 28. Prochaines étapes Publication du code client MQTT: Publication pour la fin de semaine, après nettoyage et documentation, sur le compte Github de ProcessOne(https://github.com/processone/) Présentation de ce que j'ai appris lors du design de l'API de la bibliothèque ? Mise en oeuvre de serveurs de messaging en Go: Présentation du serveur NATS ?: Illustration de NATS qui est un protocol non standard mais également très performant. Autres serveurs de messaging en Go.
  • 29. Liens Code des slides github.com/processone/talks/tree/master/2016/go-paris-meetup (https://github.com/processone/talks/tree/master/2016/go-paris-meetup) Go XMPP github.com/processone/gox(https://github.com/processone/gox) Go MQTT github.com/processone/mqtt(https://github.com/processone/mqtt) Brave New Geek: Dissecting Message Queues bravenewgeek.com/dissecting-message-queues/(http://bravenewgeek.com/dissecting-message-queues/)