Présentation de l'adaptateur UDP
Bonjour à tous,
Cet article fait suite à la question que j'avais posée à la communauté L'adaptateur UDP ne fonctionne pas
Dans cet article, je vais vous présenter les points suivants
1) Qu'est-ce que "UDP"?
2) L'état actuel d'Iris avec UDP
3) Ma solution avec l'adaptateur UDP
1) Qu'est-ce que "UDP"?
L'acronyme UDP signifie User Datagram Protocol (protocole de datagramme utilisateur). Il s'agit de l'un des principaux protocoles composant la suite IP (Internet Protocol), utilisé pour la transmission de données sur un réseau. Voici quelques fonctionnalités clés de l'UDP:
- Sans connexion : L'UDP n'établit pas de connexion avant d'envoyer des données, ce qui signifie qu'il peut envoyer des messages (datagrammes) sans échange préalable.
- Peu fiable : Il n'y a aucune garantie que les messages envoyés via l'UDP arriveront à destination. Il n'y a pas de récupération des erreurs ni de retransmission des paquets perdus.
- Vitesse : Étant donné que l'UDP est sans connexion et qu'il ne nécessite pas de vérification ou de récuperation des erreurs, il est généralement plus rapide que le TCP (Transmission Control Protocol), ce qui le rend approprié pour les applications où la vitesse est cruciale.
- Constrruit autour des datagrammes : L'UDP envoie des messages sous forme de paquets discrets, qui peuvent être de longueur variable. Chaque paquet est traité indépendamment.
- Cas d'utilisation : L'UDP est couramment utilisé dans les applications où la vitesse est plus importante que la fiabilité, telles que la diffusion vidéo en continu, les jeux en ligne, la voix sur IP (VoIP) et les communications en temps réel.
En général, l'UDP est un protocole léger qui est utile pour des applications spécifiques où une faible latence est essentielle.
2) L'état actuel d'Iris avec UDP
Bien entendu, InterSystems IRIS permet d'utiliser ce protocole pour envoyer et recevoir des données.
En tant que protocole REST, il y a deux façons de le faire :
- avec ##class(%Net.UDP).%New().
- avec EnsLib.UDP.OutboundAdapter et EnsLib.UDP.InboundAdapter
##class(%Net.UDP).%New()
Même si la documentation de la classe et très détaillée, voici le lien de la documentation d'InterSystems sur la façon de l'utiliser.
Pour envoyer/recevoir des données, il faut utiliser une instance de class(%Net.UDP).%New() et une méthode associée.
En résumé, pour envoyer des données (sur localhost avec le port 3001) :
SET client = ##class(%Net.UDP).%New()
SET addrbin = ##class(%Net.UDP).GetHostAddr("127.0.0.1")
Set status = client.Send("message text", addrbin, 3001)Pour recevoir des données (sur localhost avec le port 3001) :
Set sobj = ##class(%Net.UDP).%New(3001,"127.0.0.1")
Set data = sobj.Recv()
EnsLib.UDP.OutboundAdapter and EnsLib.UDP.InboundAdapter
Ce dernier est plus simple : c'est un adaptateur.
La documentation : EnsLib.UDP.OutboundAdapter et EnsLib.UDP.InboundAdapter
Pour envoyer des données :
Set status = ..Adapter.SendStream(stream)
Pour obtenir des données :
Set status = ..Adapter.Receive(stream)
Cependant, cela ne fonctionne pas. J'ai posé ma question à la communauté "L'adaptateur UDP ne fonctionne pas" et j'ai créé un ticket pour le WRC.
La réponse a été formulée comme suit :
Cet exécutable sous-jacent n'est plus installé dans le produit depuis Ensemble 2018.1.
J'ai vérifié au niveau interne et le JIRA DP-437486 a été soumis pour mettre à jour ces adaptateurs afin d'utiliser la classe %Net.UDP, mais cela sera soumis à l'approbation de la gestion des produits et aux ressources de développement disponibles.
Malheureusement, la seule option possible actuellement est de créer votre propre adaptateur personnalisé en utilisant la classe %Net.UDP.
Voici les deux principales différences entre la classe (%Net.UDP) et l'adaptateur EnsLib.UDP.OutboundAdapter
- La classe %Net.UDP utilise la classe système $System.UDP, elle utilise donc le code du noyau Cache/IRIS pour envoyer/recevoir les messages UDP, alors que l'adaptateur UDP utilise un tuyau de commande pour appeler des exécutables externes afin d'envoyer/recevoir le message UDP.
- La classe %Net.UDP envoie/lit une chaîne de caractères alors que l'adaptateur UDP utilise un flux pour envoyer/lire les messages.
3) Ma solution avec l'adaptateur UDP
J'ai donc écrit ma propre méthode (approuvée par le service d'assistance) pour envoyer des données :
/// Adaptateur pour l'envoi de données avec une connexion UDPClass USER.UDP.OutboundAdapter Extends Ens.Adapter
{
/// Hôte du serveur UDPProperty Host As%String [ Required ];/// Port du serveur UDPProperty Port As%Integer [ Required ];/// si 1, le texte qui sera envoyé est affichéProperty UDPTrace As%Integer(VALUELIST = ",0,1") [ InitialExpression = 0, Required ];Parameter SETTINGS = "Host:Basic,Port:Basic,UDPTrace:Basic";/// Envoi de "texte" par le biais de la connexion UDP
Method SendDataText(text As%String) As%Status
{
Try {
Set status = $$$OKIf..UDPTrace=1
{
Do..ShowText(text)
}
<span class="hljs-keyword">Set</span> udpClient = <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%Net.UDP</span>).<span class="hljs-built_in">%New</span>()
<span class="hljs-keyword">Set</span> addrbin = <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%Net.UDP</span>).GetHostAddr(<span class="hljs-built_in">..Host</span>)
<span class="hljs-keyword">Set</span> sentBytes = udpClient.Send(text, addrbin, <span class="hljs-built_in">..Port</span>)
}
<span class="hljs-keyword">Catch</span> exception {
<span class="hljs-keyword">Set</span> status = exception.AsStatus()
}
<span class="hljs-keyword">Return</span> status
}
/// Conversion du "stream" en texte et son envoi via la connexion UDP
Method SendDataStream(stream As%Stream.Object) As%Status
{
Try {
Do stream.Rewind()
Set text = ""While 'stream.AtEnd{
Set text = text _ stream.Read()
}
<span class="hljs-keyword">Set</span> status = <span class="hljs-built_in">..SendDataText</span>(text)
}
<span class="hljs-keyword">Catch</span> exception {
<span class="hljs-keyword">Set</span> status = exception.AsStatus()
}
<span class="hljs-keyword">Return</span> status
}
/// Conversion de l'"objet" en json et son envoi via la connexion UDP
Method SendDataJSONObject(object As%RegisteredObject, format As%String = "iw") As%Status
{
Try {
Set status = ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(.stream,object,,,,format)
$$$ThrowOnError(status)
<span class="hljs-keyword">Set</span> status = <span class="hljs-built_in">..SendDataStream</span>(stream)
}
<span class="hljs-keyword">Catch</span> exception {
<span class="hljs-keyword">Set</span> status = exception.AsStatus()
}
<span class="hljs-keyword">Return</span> status
}
/// Un texte est pris en entrée,/// Les traces de l'objet associé sont affichées
Method ShowText(text As%String)
{
Set nbParty = $SYSTEM.SQL.CEILING($LENGTH(text)/1100)
For ii=1:1:nbParty
{
$$$TRACE($EXTRACT(text,ii,ii+1100))
}
}
}
J'espère que cet article a été, sinon utile, du moins intéressant.
Je n'ai pas testé EnsLib.UDP.InboundAdapter, donc n'hésitez pas à ajouter plus d'informations à la discussion.
Corentin
Comments
Merci @Corentin Blondeau
Bonne initiative, je me souviens bien de ce problème.
Merci @Corentin Blondeau
pour la recherche et surtout le partage à la communauté !