| lang | fr |
|---|
- Protocole Smart Piano
- Format des messages
- Types de messages
- Diagramme de séquence
- États de la connexion
- Transitions d'états
- Règles de validation
- Gestion des erreurs de protocole
- Exemple de Jeu de notes réussi
- Exemple de Jeu d'accords avec erreur
Version: 1
Smart Piano utilise un protocole texte simple sur Unix Domain Socket (UDS) pour la communication entre le moteur de jeu (serveur) et l'interface utilisateur (client).
- Type : Unix Domain Socket (UDS)
- Chemin par défaut :
/tmp/smartpiano.sock - Mode : SOCK_STREAM (orienté connexion)
- Encodage : UTF-8
Chaque message débute par son type, comporte d’éventuelles lignes de texte au
format clé=valeur, et se termine par une ligne vide (\n\n).
type du message
clé1=valeur1
clé2=valeur2
# ligne vide ici <--
- Le type de message est en minuscules ASCII, ne contient ni espaces, ni
\n - Le type du message se termine par
\n(LF uniquement) - Les éventuelles lignes subséquentes contiennent une (seule) paire
clé=valeur - Les clés contiennent uniquement des minuscules ASCII (non accentuées) et
_ - Clé et valeur ne peuvent pas contenir
=ou\n - Clé et valeur sont séparés uniquement par
=(qui termine la clé) - La valeur peut contenir n’importe quel caractère UTF-8, sauf
\n, qui est le seul caractère à la terminer- Dans les faits, les valeurs (actuellement) acceptées sont la plupart du temps un mot en minuscules, avec parfois des chiffres
- Les lignes se terminent par
\n(LF uniquement) - Le message se termine par une ligne ne contenant pas de paire
clé=valeur- Généralement vide, donc
\n\n
- Généralement vide, donc
- Encodage UTF-8 ; Caractères accentués, spéciaux… supportés dans les valeurs
- Un message sans champ contient le type du message suivi de
\n\n
Exemple :
config
game=note
scale=c
mode=maj
# ligne vide indiquant la fin du message <--
Ci-dessous, la fin d’un bloc de code est considérée comme une ligne vide.
Commence une nouvelle session de jeu en la configurant.
config
game=<TYPE>
scale=<GAMME>
mode=<MODE>
Champs :
game: Type de jeunote: Jeu de reconnaissance de noteschord: Jeu d'accords sans renversementinversed: Jeu d'accords avec renversements
scale: Éventuelle gamme musicale voulue (sinon le serveur choisit)- Valeurs :
c,d,e,f,g,a,b - Cela équivaut en français à "Do", "Ré", "Mi", "Fa", "Sol", "La", "Si"
- Valeurs :
mode: Éventuel mode de la gamme voulu (sinon le serveur choisit)- Valeurs :
majpour Majeur,minpour mineur
- Valeurs :
Exemple :
config
game=note
scale=c
mode=maj
Indique que le client est prêt à recevoir le prochain challenge, à poursuivre le jeu en cours.
ready
Aucun champ, seulement le type valant ready, suivi d’une fin de message.
Demande l'arrêt de la session : retourne dans l’état non configuré.
quit
Aucun champ, uniquement le type valant quit, suivi d’une fin de message.
Confirme la réception de la configuration.
ack
status=ok
Exemple en cas d'erreur :
ack
status=error
code=<CODE>
message=<MESSAGE>
Champs :
status:okouerrorcode: Code d'erreur éventuelgame: Type de jeu invalidescale: Gamme invalidemode: Mode invalidemidi: Périphérique MIDI non disponible
message: Éventuel message d'erreur descriptif
Demande au joueur de jouer une note spécifique.
note
note=<NOTE>
id=<ID>
Champs :
note: Note à jouer (ex :c4,d#5,gb3)id: Identifiant unique du challenge (entier positif)
Exemple :
note
note=c4
id=1
Demande au joueur de jouer un accord spécifique.
chord
name=<NOM>
notes=<NOTES>
id=<ID>
Champs :
name: Nom (affiché) de l'accord (ex :Do majeur,Re mineur)- Commence par le nom de la fondamentale en notation syllabique
- Suivi de l’adjectif
majeuroumineur - Éventuellement suivi par un chiffre arabe indiquant le renversement
notes: Notes de l'accord (ex :c4 e4 g4)- Une note commence par une lettre minuscule entre
aetg - Suivie éventuellement d’un dièse (
#) ou bémol (b) - Terminé par un chiffre d’octave de 0 à 8 (ex :
4) - Les notes sont séparées par des espaces
- Une note commence par une lettre minuscule entre
id: Identifiant unique du challenge
Exemple (position fondamentale) :
chord
name=Do majeur
notes=c4 e4 g4
id=5
Exemple (premier renversement) :
chord
name=Do majeur 1
notes=e4 g4 c5
id=6
Informe le joueur du résultat de sa tentative, clôturant le challenge.
result
id=<ID>
correct=<NOTES>
incorrect=<NOTES>
duration=<MS>
Champs :
id: Identifiant du challenge correspondantcorrect: Éventuelles notes (séparées par des espaces) jouées a raisonincorrect: Éventuelles notes jouées alors que non attenduesduration: Éventuelle durée en millisecondes entre l’envoi du challenge et la réception des notes jouées
Un message de résultat contient au moins une note, qu’elle soit correcte ou incorrecte.
Exemple (correct) :
result
id=1
correct=c4
Exemple (incorrect) :
result
id=2
incorrect=d4
Indique la fin de la session de jeu avec un récapitulatif.
over
duration=<DURATION>
perfect=<CORRECT>
partial=<PARTIAL>
total=<TOTAL>
Champs :
duration: Durée depuis le dernier messageconfigen millisecondesperfect: Éventuel nombre de challenges sans notesincorrectpartial: Éventuel nombre de challenges avec au moins une notecorrectet une noteincorrecttotal: Nombre total de challenges joués
Exemple :
over
duration=45
perfect=10
total=10
Signale une erreur détectée par le serveur.
error
code=<CODE>
message=<MESSAGE>
Champs :
code: Code d'erreurinternal: Erreur interne du serveurprotocol: Erreur de protocole (message mal formé)state: État invalide (ex : ready sans config)midi: Erreur MIDI
message: Message d'erreur descriptif
Smart Piano essaie d’être tolérant aux erreurs. Seule l’erreur interne engendre un retour en état sûr. Les autres erreurs engendrent simplement un avertissement du client (qui avertit l’utilisateur si besoin) et un maintien de l’état actuel.
Par exemple, en cas de périphérique MIDI indisponible, le serveur envoie une erreur pour indiquer à l’utilisateur de reconnecter son piano, mais la session de jeu peut continuer une fois le piano reconnecté.
Exemple :
error
code=protocol
message=Message mal formé: champ 'id' manquant
Client Serveur
| |
|--- config ----------------->|
| |
|<-- ack (ok) ----------------|
| |
|--- ready ------------------>|
| |
|<-- note --------------------|
| |
| [Joueur joue une note] |
| |
|<-- result ------------------|
| |
|--- ready ------------------>|
| |
|<-- note --------------------|
| |
| [Répéter pour N challenges] |
| |
|<-- over --------------------|
| |
Client Serveur
| |
|--- config ----->|
| (invalide) |
| |
|<-- ack (error) -|
| |
|--- config ----->|
| (valide) |
| |
|<-- ack (ok) ----|
| |
- DISCONNECTED : Aucune connexion établie, état de départ
- CONNECTED : Client connecté, mais pas de configuration
- CONFIGURED : Configuration reçue et validée, prêt à lancer le jeu
- PLAYING : Challenge émis, jeu en cours, attente d’une action du joueur
- PLAYED : Note(s) jouée(s) (MIDI), prêt pour jouer à nouveau
DISCONNECTED --[client connect]--> CONNECTED
CONNECTED --[config + ack]--> CONFIGURED
CONFIGURED --[ready + challenge]--> PLAYING
PLAYING --[note(s) played]--> PLAYED
PLAYED --[ready]--> PLAYING
PLAYING --[last challenge done + result]--> CONFIGURED
CONFIGURED --[quit / internal error]--> CONNECTED
PLAYING --[quit / internal error]--> CONNECTED
PLAYED --[quit / internal error]--> CONNECTED
- Tous les champs obligatoires (non "éventuels") doivent être présents
- Les valeurs des champs doivent être dans les ensembles autorisés
- Le message doit se terminer par
\n\n - Timeout de réception après 90 secondes
- Éviter les connexions zombies, mais laisser le temps de jouer
Le serveur doit aussi s’assurer que le challenge id est unique et croissant,
réinitialisé à chaque nouvelle configuration.
En cas d'erreur de protocole (message mal formé, champ manquant, valeur invalide), le serveur doit :
- Journaliser (log) l'erreur, comme n’importe quel échange (pour debug)
- Envoyer un message
erroravec le code et message appropriés - Fermer la connexion si l'erreur est critique
- Continuer la session si l'erreur est récupérable
→ config
→ game=note
→ scale=c
→ mode=maj
→
← ack
← status=ok
←
→ ready
→
← note
← note=c4
← id=1
←
[Joueur joue C4]
← result
← id=1
← correct=c4
←
→ ready
→
← note
← note=e4
← id=2
←
[Joueur joue E4]
← result
← id=2
← correct=e4
←
[... après 10 challenges ...]
← over
← duration=32
← perfect=10
← total=10
←
→ config
→ game=inversed
→ scale=c
→ mode=maj
→
← ack
← status=ok
←
→ ready
→
← chord
← name=Do majeur
← notes=c4 e4 g4
← id=1
←
[Joueur joue C4 E4 F4 - erreur!]
← result
← id=1
← correct=c4 e4
← incorrect=f4
←
→ ready
→
← chord
← name=Do majeur
← notes=c4 e4 g4
← id=2
←
[Joueur joue C4 E4 G4 - correct!]
← result
← id=2
← correct=c4 e4 g4
←
...