Protocol
La communication entre le serveur et les client se fait par message rpc encodé en protobuf, dans cette partie nous verrons les détails.
Remote Procedure Call (RPC)
Le RPC est un protocole réseau permettant l'éxécution de taches sur un serveur depuis un client. Cette solution semble être bonne pour construire un marché ou les ordres sont demandé par le client et effectué par le serveur.
Le client envois un premier une requête et bloque en attendant une réponse. Dans le cas de ce serveur le client à le choix entre 3 requêtes:
- Requête d'identification: permet au serveur de charger la session ou d'en créer une si elle n'existe pas, la réponse contient l'identifiant de la session.
- Requête de la liste des titres: le serveur renvoie la liste des titres disponible avec une courte description de chacuns.
- Requête d'ordres: le serveur execute et renvois le résultat des ordres.
Protobuf
Protocol Buffers est un format de sérialisation et de description d'interface développé par Google. Originellement conçut pour un nombre limité de languages nous utiliserons une implementation open-source pour Rust appelé prost!.
Language de description d'interface
Les language de description d'interface permettent de définir des composants de logiciel dans un language neutre de l'implementation de ce dernier. C'est à dire que si un fichier de description est partagé entre un serveur et un client, ils pourront être implémenté dans différents languages de programmation car ils auront la description des éléments pour désérialiser les données.
Ex:
Le protobuf
message Ordre {
uint64 qt = 1;
double prix = 2;
}
devient en rust:
pub struct Ordre {
qt: u64,
prix: f64,
}
et en java:
public class Ordre {
long qt;
double prix;
}
Sérialisation/Désérialisation
La désérialisation est le fait de réduire une structure de donnée d'un programme en un ensemble cohérent en binaire. La sérialisation, qui est l'inverse de la désérialisation, est le fait de créer un structure de donnée depuis un ensemble cohérent d'information binaire.
Couplé ensemble ils permettent de stocker des structures de données dans des bases de données ou d'envoyer ces premières à travers des réseaux. En effet, si un client et un serveur possèdent la même structure ils peuvent s'échanger des information structuré facilement en restructurant les informations de l'autre.
Transmission
Les clients se connectent via TCP (Transmission Control Protocol) pour emmettre les message RPC.
Concernant les information de quantité sont relayé via un système de multicasting en UDP (User
Datagram Protocol), c'est à dire un système ou le serveur envoie de la donnée à une adresse et les
clients qui le souhaite récupèrent la donnée sans que le serveur ai à entretenir une connection ou
compter les personnes lisant les quantités. Auquel cas Le message protobuf envoyé est Broadcast
.
Protocol entier
syntax = "proto3";
package protocol;
// Buy/Sell tag for an order
enum Kind {
Buy = 0;
Sell = 1;
}
// Security
// security_id: id to use if you want to place orders
// description: description of the security
message Security {
uint64 security_id = 1;
string description = 2;
}
// SecurityBroadcast
// security: affected security
// quantity: current quantity
message SecurityBroadcast {
Security security =1;
double quantity = 2;
}
// Broadcast
// broadcast: all updates on securities
message Broadcast {
repeated SecurityBroadcast broadcast = 1;
}
// Order
// security_id: targeted security
// kind: direction of the order
// amount: amount bought/sold
message Order {
uint64 security_id = 1;
Kind kind = 2;
double amount = 3;
}
// Result of an order
// security_id: targeted security
// kind: direction of all orders for a security
message OrderResult {
uint64 security_id = 1;
Kind kind = 2;
double balance = 3;
}
// Request to get the list of securities
message RequestSecurities {}
// Response with all the availabe securities
message ResponseSecurities {
repeated Security securities = 1;
}
// Request to get authenticated to the server
message RequestAuthenticate {}
// Response to authentication request with the uuid
message ResponseAuthenticate {
bytes uuid = 1;
}
// Request to place orders
message RequestOrder {
repeated Order orders = 1;
}
// All the order results
message ResponseOrder {
repeated OrderResult orders = 1;
}
// Unified response type
message Response {
uint32 id = 1;
oneof response {
ResponseAuthenticate auth = 2;
ResponseOrder order = 3;
ResponseSecurities security = 4;
}
}
// Unified request type (uuid can be empty before authentication)
message Request {
uint32 id = 1;
bytes uuid = 2;
oneof request {
RequestAuthenticate auth = 3;
RequestOrder order = 4;
RequestSecurities security = 5;
}
}