Conception et réalisation d'une plateforme applicative pour le protocole SIP Sébastien Pierre . Alcatel R&D Université Technologique de Belfort-Montbéliard 21 July, 2003 Résumé Ce document constitue à la fois mon rapport de projet de fin d'études en tant qu'ingénieur et le mémoire de DEA effectué en parallèle de mon cursus d'ingénieur. Le projet dont traite ce document concerne la conception et la réalisation d'une plateforme logicielle permettant la réalisation d'applications basées sur le protocole SIP (Session Initiation Protocol). Ce protocole, utilisé dans le contexte de la téléphonie et de la conférence sur Internet se trouve être un protocole extensible destiné à trouver des applications en dehors du cadre de la téléphonie. A la lumière d'une analyse des caractéristiques des applications SIP, nous détaillons notre proposition mélangeant systèmes d'agents, programmation réactive et concurrente et langages embarqués spécialisés dans le domaine concerné par les applications SIP. A la fois technique et théorique, ce document balaie un ensemble large de domaines et vise à apporter une perspective nouvelle au développement d'applications de communication, en se basant sur un ensemble de travaux académiques et de logiciels libres. Mots-clé: Protocole SIP, système d'agents, programmation réactive, programmation concurrente, langages de domaines. Conception et réalisation d'une plateforme applicative pour le protocole SIP Remerciements Je tiens tout d'abord à remercier Armand Marchesin pour avoir su garder son authenticité et défendre vaillament sa position alternative au sein d'une environnement pas toujours conciliant. Il a su me prouver qu'il reste encore un peu de place pour l'innovation, même au sein de cette terre aride qu'est l'industrie. Je tiens également à remercier mes comparses ; Sham pour m'avoir initié à la machine à café d'Alcatel, les deux Matthieu, Julien, Jean-Charles et Fadhi, avec qui ce fut un plaisir de débattre entre deux bouchées de frites. Enfin, et surtout, je n'oublie pas ma chère Pauline qui se dévoue en ces temps d'urgence pour me permettre de boucler mon travail dans la bone humeur. 2 Conception et réalisation d'une plateforme applicative pour le protocole SIP 3 Conception et réalisation d'une plateforme applicative pour le protocole SIP Table des matières 1. Introduction .. .. .. .. .. .. .. 1.1. Alcatel .. .. .. .. .. .. 1.2. La téléphonie et Internet .. .. 1.3. Propos du projet .. .. .. .. 2. Contexte, analyse et proposition .. .. 2.1. Contexte et problématique .. .. 2.1.1. Le protocole SIP .. .. 2.1.2. Les applications SIP .. 2.1.3. Détails du protocole SIP 2.1.4. Objectif du projet .. 2.2. Analyse .. .. .. .. .. .. 2.2.1. Perspectives et exigences 2.2.2. Logiciels existants .. .. 2.2.3. Domaines de recherche 2.3. Proposition .. .. .. .. .. 2.3.1. Approche .. .. .. 2.3.2. Décomposition .. .. 2.3.3. Synthèse .. .. .. .. 3. Réalisation .. .. .. .. .. .. .. .. 3.1. Organisation .. .. .. .. .. 3.1.1. Contraintes .. .. .. 3.1.2. Modèle de développement 3.1.3. Infrastructure .. .. .. 3.1.4. Planning .. .. .. .. 3.2. La plateforme agent .. .. .. 3.2.1. Introduction .. .. .. 3.2.2. Besoins .. .. .. .. 3.2.3. Problèmes .. .. .. 3.2.4. Proposition .. .. .. 3.2.5. Réalisation .. .. .. 3.2.6. Synthèse .. .. .. .. 3.3. L'intégration du protocole SIP .. 3.3.1. Introduction .. .. .. 3.3.2. Besoins .. .. .. .. 3.3.3. Problèmes .. .. .. 3.3.4. Proposition .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 6 6 7 7 9 9 9 10 11 14 15 15 17 19 23 23 27 29 30 30 30 31 32 33 33 34 35 36 41 46 46 46 46 47 48 48 4 Conception et réalisation d'une plateforme applicative pour le protocole SIP 3.3.5. Réalisation 3.3.6. Synthèse .. 3.4. Le langage de domaine 3.4.1. Introduction 3.4.2. Besoins .. 3.4.3. Problèmes 3.4.4. Proposition 3.4.5. Réalisation 3.4.6. Synthèse .. 4. Synthèse .. .. .. .. .. 4.1. Réalisation .. .. 4.2. Organisation .. .. 4.3. Conclusion .. .. References .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. 51 60 60 61 61 63 64 65 76 77 77 78 80 82 5 Conception et réalisation d'une plateforme applicative pour le protocole SIP 1. Introduction Ce document constitue le rapport concernant mon projet de fin d'études d'ingénieur ainsi que mon mémoire de DEA. Le projet que j'ai effectué au sein du département Recherche et Développement d'Alcatel à Illkirch (Bas-Rhin) a trait au domaine des télécommunications et notamment du protocole SIP (Session Initiation Protocol) qui représente la transition d'une infrastructure téléphonique classique (Réseau Téléphonique Commuté) au support flexible qu'est Internet. Au cours de ce document à la structure particulière de par sa double approche (ingénierie et recherche), nous aborderons en premier lieu le contexte et la problématique par une présentation analytique du protocole SIP, au regard des objectifs de mon projet de fin d'études. Nous effecturons ensuite une brève analyse des perspectives et exigences liés au protocole SIP, puis nous présenterons brièvement un ensemble de logiciels existants concernés par SIP. Nous détaillerons alors les domaines de recherche concernés par notre objectif. Au regard de ces domaines et des exigences définies, nous présenterons notre proposition, en la justifiant et en proposant une décomposition permettant d'anticiper une architecure. C'est en second lieu que nous détaillerons la réalisation de notre objectif, en présentant la méthodologie et en détaillant de manière cohérente la réalisation de chaque module. Nous reprendrons alors l'ensemble de notre analyse, de notre proposition et de sa réalisation, de manière à exprimer une synthèse de ce projet de fin d'études. Ce document, relativement long, ne comporte pas véritablement d'état de l'art des domaines abordés, mais propose plutôt une perspective dont les motivations sont appuyées par un ensemble choisi de travaux de recherche. Cela dit, et à titre d'introduction, nous allons présenter brièvement la société Alcatel, puis nous aborderons les évolutions permises par Internet dans le cadre des télécommunications. Nous présenterons ensuite l'objectif du projet avant d'entrer dans la première grande partie de ce document. 1.1. Alcatel Alcatel est une entreprise française résultant de multiples absorptions depuis la création de la Compagnie Générale de l'Electricité en 1898. Tout d'abord centrée sur la production de matériels électriques (essentielement ferroviaires), c'est par le rachat de la Société Alsacienne de Constructions Atomiques de Télécommunications et d'Electronique (Alcatel) en 1962 que la CGE étend son secteur d'activité aux systèmes de communication. En 1980, le groupe est nationalisé et prend le nom d'Alcatel-Alsthom, il couvre alors un large panel de domaines: du téléphone aux activités spatiales en passant par le transport, l'énergie et l'électronique professionnelle. C'est dans les années 1990 qu'Alcatel-Alsthom revient au secteur privé, se séparant en deux entités plus spécialisées: Alcatel dans le métier des télécommunications, et l'électromécanique pour Alsthom. L'explosion de la bulle spéculative des valeurs de la «nouvelle économie» engendre une crise grave au début des années 2000 et pousse Alcatel à se séparer de certaines de ses activités, comme une partie de la fabrication matérielle. Alcatel n'est donc pas une entreprise disposant d'une forte culture informatique, dans le sens où le logiciel n'est pas considéré comme le métier de l'entreprise cette impression est avant tout basée sur l'orientation matérielle qu'avait auparavant Alcatel. Pourtant c'est bien aujourd'hui dans le domaine 6 Conception et réalisation d'une plateforme applicative pour le protocole SIP du logiciel que semble se dessiner l'avenir des métiers des télécommunications, principalement grâce à l'expansion d'Internet. 1.2. La téléphonie et Internet La croissance et la démocratisation du réseau Internet a un impact non négligeable sur le domaine de la téléphonies En offrant une abstraction de la topologie du réseau et en se focalisant sur le transport de données, Internet offre une infrastructure globale permettant de réaliser quasiment tous les moyens de télécommunications que nous connaissons actuellement. En comparaison, le RTC (réseau téléphonique commuté) ne permet pas une grande flexibilité car il repose énormément sur des technologies propriétaires, peu adpatées à une utilisation autre que celle prévue au départ. Par opposition, Internet et sa conception autour de standards ouverts (tels que TCP/IP ou encore HTTP) offrent une infrastructure abstraite, généraliste et flexible, apte à un grand nombre d'utilisations dont beaucoup n'ont pas été prévues au départ. Une autre différence entre le RTC et Internet est que le premier est architecturé de telle sorte que les services sont fournis par les entités au centre du réseau, et que les terminaux ne sont donc pas capables de créer des service eux-même. Par opposition, Internet offre un modèle où ce sont justement les terminaux qui peuvent offrir les fonctionnalités: on peut tres facilement faire de la téléphonie par Internet, simplement avec deux ordinateurs disposant des logiciels adéquats, alors qu'il n'y a pas d'opérateur entre ces deux ordinateurs pour permettre le transfert de la voix. Depuis quelques années un ensemble de technologies sont apparues pour reproduire les services offerts par le réseau téléphonique, mais en utilisant le réseau Internet. Outre un transport de la voix bien moins cher sur les longues distances, l'utilisation d'Internet comme médium permet d'étendre l'ensemble des informations liées à une communication vocale, comme de multiples informations de contrôle (appeller, décrocher, raccrocher, mettre en attente, etc), ou encore l'adjonction d'autres canaux tels que la vidéo. En parallèle, des travaux sont effectués pour permettre d'instaurer la QOS (qualité de service) faisant actuellement défaut à Internet. En effet, la QOS permet de s'assurer que des données auront un traitement prioritaire sur d'autres cette fonctionnalité est essentielle pour toutes les données appartenant à une communication en temps réel, où la latence doit être minimale (c'est le cas des communications vocales ou vidéo). Le réseau Internet offre donc une infrastructure plus flexible et plus généraliste, sur laquelle il semble possible de réaliser l'ensemble des services de la téléphonie sur RTC. Le rôle du protocole SIP est ici de participer à cette réalisation de services de communication (et notammant la vidéoconference) sur le réseau Internet. 1.3. Propos du projet La téléphonie considère deux problématiques distinctes dans le contexte d'une communication: ­ ­ Le transport de la voix Les informations de contrôle. 7 Conception et réalisation d'une plateforme applicative pour le protocole SIP Le transport de la voix et les informations de contrôle (appeller, décrocher, mettre en pause, raccrocher, etc) sont deux flux distincts, alimentés à des rythmes différents, et qui n'ont donc pas besoin d'être acheminés par les mêmes canaux ; ces deux flux d'informations se voient effectivement séparés dans le RTC que nous connaissons. Cette décomposition est préservée dans les propositions de technologies relatives aux communications vocales sur Internet, où l'on voit des protocoles dédiés au transport de données temps-réel (Real Time Protocol), dont la voix (Voice on IP), mais également des protocoles dédiés à la communication d'informations de contrôle, comme c'est le cas du protocole SIP (Session Initiation Protocol). Dans le sens où SIP est avant tout un protocole de contrôle, ce dernier est de nature flexible et peut s'appliquer à de nombreux domaines autre que la voix ou la vidéo, comme par exemple la messagerie instantanée ou la communication d'informations (comme la météo). On qualifie d'application SIP un logiciel qui utilise et s'articule autour du protocole SIP, comme par exemple un téléphone logiciel utilisant SIP, mais également des logiciels fournissant des services de communication, comme le renvoi, le rappel, ou toute autre utilisation reposant sur les principes du protocole SIP (que nous allons aborder sous peu). Le propos du présent projet est de réaliser une plateforme permettant la réalisation d'applications SIP, sans présupposé quand à la nature de ces applications, qui peuvent naturellement être de type téléphonie ou visioconférence, mais qui peuvent également être différentes. Cette plateforme devrait se baser au maximum sur des logiciels libres1.Nous allons, au cours de la section suivante présenter brièvement le protocole SIP, et aborder en détail le contexte et les problématiques que nous considérons comme relatives à l'utilisation du protocole. Ce que l'on appelle également open source, c'est à dire des logiciels dont les sources sont accessibles à tous, et que l'on peut modifier et réutiliser sous diverses conditions 1 8 Conception et réalisation d'une plateforme applicative pour le protocole SIP 2. Contexte, analyse et proposition La présente partie a pour but de présenter le protocole SIP, ses enjeux, ses possibilités et les problèmes qu'il soulève. Nous allons au cours de cette section présenter celui-ci ainsi que les problématiques qui y sont rattachées. Nous analyserons par la suite les exigences liées à ce protocole, et présenterons brièvement les réponses proposées par les logiciels existants. Nous aborderons ensuite l'ensemble des domaines de recherche qui sont concernés au regard de notre analyse. Nous concluerons ensuite par une proposition résultant de l'analyse effectuée jusque là. Encore une fois, nous insistons sur le fait que nous n'effectuons pas un état de l'art, mais que nous développons notre perspective en s'appuyant sur des travaux effectués et des domaines de recherche spécifiques. 2.1. Contexte et problématique 2.1.1. Le protocole SIP Initié en 1996 au sein de l'Internet Engineering Task Force, le protocole SIP, acronyme de (Session Initiation Protocol), avait pour but initial de permettre l'utilisation de la vidéo-conférence sur Internet. En effet, et comme son nom l'indique, le protocole SIP permet de créer (d'initier) des sessions interactives entre plusieurs entités communicantes1. La notion de session interactive représente en fait un échange d'information dont le déroulement peut être modifié par l'intervention des entités participant à cet échange. La création et l'utilisation de ces sessions implique un ensemble de fonctionnalités auxquelles le protocole SIP répond: Localisation: Il doit être possible de déterminer facilement à partir d'un même référant une entité avec laquelle on désire communiquer. Pour ce faire, le protocole SIP utilise les URI (Uniform Resource Indicator), qui reprennent la syntaxe des adresses e-mail couramment utilisées (par exemple, sip:sebastien@alcatel.fr). Négociation: Avant que la session ne soit crée, les interlocuteurs doivent négocier la qualité des informations qui vont êtres échangées. Les interlocuteurs pourront ici choisir par exemple quels sont les médias qu'ils préfèrent (vidéo, voix, texte, etc) éventuellement en fonction de leurs terminaux respectifs2. Contrôle: Une fois la session créée, il faut pouvoir intervenir sur son déroulement, et plus particulièrement l'interrompre. En outre, certaines fonctionnalités plus avancées comme le changement de terminal (et donc éventuellement de médium) sont possibles. La négocitation peut être considérée comme un mécanisme résultant du contrôle. 1 Le terme générique d'entité permet de mettre l'accent sur le fait qu'il n'y a pas forcément que des humains dans la conversation 2 C'est d'ailleurs dans ce contexte qu'intervient le protocole SDP (Session Description Protocol) que nous aborderons plus loin 9 Conception et réalisation d'une plateforme applicative pour le protocole SIP Il est à noter que SIP ne prend pas en charge le transport des informations (transport du son, de la vidéo, etc), tâche qui incombe plutôt à des protocoles spécialisés, tels que RTP (Real Time Protocol). Cette décomposition respecte la décomposition pratiquée en téléphonie classique, comme nous l'avons présenté auparavant. SIP s'inscrit donc comme un protocole facilitant les interactions au sein du réseau Internet, en offrant un ensemble de fonctionnalités permettant d'instaurer et de contrôler une session de communication. Il faut noter par ailleurs que conformément à la philosophie de l'IETF, le protocole SIP est conçu de manière à encapsuler des données dont il ne connait pas la signification1. D'un point de vue technique, le protocole SIP se situe au niveau applicatif, au dessus du protocole IP. Comme nous l'avons dit, SIP peut être utilisé indifféremment avec le protocole UDP ou TCP, quoique la majorité des implantations du protocole SIP communiquent en utilisant le protocole UDP. Le protocole SIP est un protocole textuel, par opposition à un protocole binaire, et est conçu de telle sorte que les messages qui lui appartiennent soient facilement lisibles par un humain. Le protocole SIP est utilisé dans la téléphonie sur Internet, et dans la vidéoconférence, en corrélation avec le protocole SDP (Session Desciption Protocol). Ce dernier permet de décrir les capacités et préférences d'un terminal vis-à-vis des médias qu'il est capable d'envoyer et de recevoir. SDP joue le rôle de support lors du processus préalable de négotiation de la communication. Bien que souvent utilisé avec SIP, SDP n'est pas lié à SIP, et SIP n'est également pas dépendant de SDP. Au niveau des logiciels, il existe actuellement bon nombre d'implantations commerciales du protocole SIP, mais seulement quelques implantations libres, dont nous allons en présenter deux un peu plus loin. Le protocole SIP est documenté dans les RFC 2543 [29] (1999) et 3261 [31] (2002), mais comporte encore maintenant des zones d'ombres comme notamment la translation d'adresses, le passage au travers de pare-feu, ou encore la gestion de la sécurité. 2.1.2. Les applications SIP Le but de SIP est en premier lieu d'offrir un espace où la localisation d'une entité est uniforme: l'équivalent des numéros de téléphone sur le réseau Internet (c'est le rôle premier des informations de contrôle). SIP offre comme nous l'avons brièvement présenté des référents qui sont en fait des URI (préfixées de sip: pour indiquer qu'elle appartiennent au protocole SIP). L'utilisation des URI permet en fait de créer un espace d'adressage s'intégrant parfaitement dans l'infrastructure actuelle, puisque les URI sont utilisées pour les deux applications Internet les plus connues et utilisées: le Web et le mail. A l'inverse des numéros de téléphone, les adresses SIP désignent une entité plutôt qu'un terminal. Cette différence fondamentale permet à celles-ci de représenter un individu, quelque soit sa localisation physique, et également quelque soit le terminal à sa disposition. L'application fondamentale de SIP est donc de permettre à deux individus de se contacter, indépendamment de leur localisation et de leur terminal. SIP permet de mettre en oeuvre une partie des services que l'on trouve dans la téléphonie, dont les principaux sont les suivants: 1 Ce qui signifie que l'on peut embarquer n'importe quel message/donnée dans un message SIP 10 Conception et réalisation d'une plateforme applicative pour le protocole SIP ­ ­ ­ La mise en attente ou en garde d'un appel Le transfert d'appel L'obtention d'informations sur l'appelant Mais également des services plus complexes, comme notamment: ­ ­ ­ ­ La téléconférence Les messages instantanés Le filtrage d'appel (en général suivant des préférences utilisateur) La facturation On trouvera d'ailleurs dans l'article intitulé "Implementing Intelligent Network Services with the Session Initiation Protocol" [33] une liste exhaustive de services téléphonique et la manière de les réaliser avec le protocole SIP. En dehors des applications inspirées de la téléphonie, SIP permet d'offrir facilement les fonctionnalités suivantes, qui répondent à des problématiques plus «informatiques»: ­ ­ ­ ­ ­ ­ ­ ­ Enregistrer des entités SIP (téléphones, PDAs, ordinateurs) Authentifier, habiliter (authorization) et gérer des comptes utilisateur Obtenir l'IP de l'autre point de la communication Router les requêtes au serveur approprié Permettre la mobilité de réseau et de terminal Enregistrer, filtrer et publier de l'information de présence (disponible, occupé, etc) Informer les utilisateurs de l'évolution d'une communication, de son succès ou de son échec. Transmettre des requêtes de qualité de service à d'autres éléments du réseau. SIP étant extensible et relativement abstrait, il offre une infrastructure au sein de laquelle de nouveaux service peuvent émerger. Il est néanmoins difficile à l'heure actuelle de prédire quels seront ces nouveaux services [37], car il arrive fréquemment qu'un outil trouve des utilisations auxquelles ses concepteurs n'ont initialement pas pensé. 2.1.3. Détails du protocole SIP Afin de bien comprendre l'ensemble de ce document, il est nécessaire d'avoir une compréhension suffisamment large du protocole SIP. Les précédentes sections ont présenté le cadre et les fonctionnalités de celui-ci. Nous aborderons ici les concepts, la terminologie et l'architecture du protocole SIP. Avant d'entrer dans le détail de SIP, il faut savoir que nous considérons des entités SIP communiquant par envoi de messages. Ces entités sont appelées UA (agents utilisateur). Les messages: requêtes et réponses 11 Conception et réalisation d'une plateforme applicative pour le protocole SIP Le protocole SIP est réalisé par échange de messages au format texte. Chaque message est composé d'une adresse (une URI SIP), d'un ensemble d'en-têtes, et d'un corps. L'exemple suivant montre un message SIP initiant une communication: INVITE sip:bob@172.25.49.134:5080 SIP/2.0 Via: SIP/2.0/UDP 172.25.49.134:5070;branch=z9hG4bK3563508590 From: ;tag=2174475352 To: Call-ID: 2188029631@172.25.49.134 CSeq: 20 INVITE Contact: Max-Forwards: 10 User-Agent: oSIP/Linphone-0.10.2 Content-Length: 0 Exemple 1 Un message d'invitation SIP Les messages SIP sont échangés entre deux entités sur un mode client-server: l'entité appelante envoie un message (une requête) a l'entité appelée. L'entité appelée répondra par un autre message (une réponse) envoyé à l'appelé. Dans ce contexte, l'appelant est considéré comme le client, l'appelé comme le serveur et l'échange de message comme une transaction. La figure 1 illustre l'établissement d'une communication entre deux personnes disposant de terminaux SIP, et permet d'observer les transactions qui s'opèrent entre eux. D'après le modèle client-serveur, les messages sont classés en deux catégories: Les requêtes: Elles constituent les messages qualifiés par un performatif (invitation, demande d'information, souscription et publication d'information, etc) appelé méthode, définissant la qualité de la transaction. Les réponses: Elles constituent les informations renvoyées par le serveur au client, et concernent autant l'évolution de la transaction que les erreurs pouvant survenir (transport, serveur, client, etc). On distingue les réponses provisionnelles, qui donnent une information optionnelle, et les réponses finales qui clôturent une transition. Il est à noter qu'une transaction SIP est initiée par une requête, suivie d'une ou plusieurs réponses. Certaines transactions sont conclues par un acquittement (acknowledgement) permettant de s'assurer de la clôture de la transaction. La sémantique des requêtes Afin de mieux saisir les possibilités offertes par SIP, voici une liste des principales méthodes définies par SIP (et utilisés pour qualifier les requêtes): 12 Conception et réalisation d'une plateforme applicative pour le protocole SIP Figure 1. Initiation d'une session avec SIP ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ INVITE: Invite une entité SIP à entrer en communication. Cette requête permet d'initier une session. ACK: Accusé de reception, utilisé pour confirmer une réponse à une requête INVITE, dans certains cas pour s'assurer de la cloture d'une transaction. PRACK: Accusé de réception pour confirmer une réponse provisionnelle. BYE: Clôture de la session. CANCEL: Annulation d'une session en instance REGISTER: Enregistrement de l'URI d'une entité SIP. OPTIONS: Demande de précision concernant les options et les capacités d'une entité SIP. REFER: Redirection d'un UA vers une URI. SUBSCRIBE: Souscription à un évènement. NOTIFY: Publication d'un évènement. MESSAGE: Envoi d'un message. On voit que le premier groupe de méthodes (INVITE, ACK, PRACK, BYE et CANCEL) permettent de gérer la création, l'interruption et la cloture d'une session. Ce sont ces méthodes qui posent la base des fonctionnalités de SIP. 13 Conception et réalisation d'une plateforme applicative pour le protocole SIP Suivent ensuite les méthodes REGISTER, OPTIONS et REFER qui répondent chacune à un besoin spécifique. La première permet à un agent SIP de s'enregistrer sur un serveur de localisation, la seconde permet de demander les capacités d'un serveur et enfin la troisième permet de dire à un agent de se référer à un autre serveur. On notera plus spécifiquement les trois dernières méthodes (SUBSCRIBE, NOTIFY et MESSAGE), car elles posent une infrastructure de communication extrêmement utile pour la communication entre logiciels1, elles permettent en effet les deux modes de communications (message et publication/souscription) utilisés dans les intergiciels (middleware) pour la communication entre objets distants. On entrevoit donc ici des applications de SIP en dehors de la téléphonie, plus orientées vers une communication généraliste. Terminologie Il est important de clarifier les termes spécifiques au protocole SIP qui vont être employés dans ce document. Voici un récapitulatif des termes importants: Agent Utilisateur: Un agent utilisateur (UA, de User Agent) est une entité utilisant le protocole SIP pour communiquer. On se réfère souvent à une application de téléphonie SIP comme un agent utilisateur. Transaction: Une transaction est un échange de messages entre un agent utilisateur client (UAC) et un agent utilisateur serveur (UAS). Requête: Une requête est un message qui initie une transaction. Réponse: Une réponse est un message envoyant une information suite à une requête. Une réponse ou plusieurs réponses clôturent une transaction. Méthode: Une méthode est un mot définissant la sémantique d'une requête. Service: Un service est l'ensemble de réponses et éventuellement de transactions résultant d'une requête. 2.1.4. Objectif du projet Nous venons de présenter plus en détail le protocol SIP, nous sommes donc en mesure de mieux comprendre l'objectif du projet. Tout d'abord, reprenons-en l'énoncé: il s'agit de"réaliser une plateforme pour applications basées sur le protocole SIP". La première chose à se demander est quel sens est donné aux mots plateforme et application. Le sens du mot application est relativement vague, et peut être en fait associé à tout ce qui utilise le protocole SIP. Une application basée sur le protocole SIP serait donc une application dont les fonctionnalités principales reposeraient fortement sur les caractéristiques et fonctionnalités relatives au protocole SIP (facilités de localisation, négociation, etc). 1 L'échange de données, l'appel de procédures distantes, etc. 14 Conception et réalisation d'une plateforme applicative pour le protocole SIP Le sens du mot plateforme quand à lui est un peu moins vague: il s'agit de proposer un ensemble d'abstractions fournissant les éléments de base qui permettent la réalisation des applications auxquelles se destine la plateforme. La plateforme peut également fournir un cadre méthodologique particulier. Le propos est donc d'offrir un cadre dans lequel le développement de logiciels s'appuyant sur le protocole SIP est facilité. Nous allons présenter dans la section suivante les différentes perspectives offertes par le protocole SIP, et plus particulièrement les exigences qui y sont liées. Ceci nous permettra de mieux entrevoir les caractéristiques de la plateforme que nous voulons réaliser. 2.2. Analyse Nous venons de présenter le protocole SIP, et nous avons vu qu'il se positionne avant tout comme un outil permettant la mise en place et le contrôle de canaux de communication entre des entités référencées dans l'espace qu'il crée. Parmi les services qu'il est susceptible d'offrir se comptent effectivement les services de téléphonique que nous connaissons, mais également bon nombre de services liés à l'intégration et la coordination de différents flux d'information. Bien qu'il soit à l'heure actuelle encore difficile d'imaginer précisément l'ensemble de ces nouvelles applications, il est cependant possible d'en anticiper les caractéristiques en analysant l'environnement informatique actuel et les problèmes que l'on retrouve dans de nombreux domaines. 2.2.1. Perspectives et exigences Une infrastructure de communication extensible Les deux aspects fondamentaux offerts par SIP sont l'enregistrement et la localisation d'entités SIP, ainsi que le mécanisme d'initiation de communication entre deux entités SIP. Nous avons également vu que le modèle transactionnel sur lequel est basé SIP ne contraint pas la sémantique des messages qui sont échanges. Ainsi, SIP offre un vocabulaire de base très orienté vers les communications vocales, avec éventuellement de la vidéo, mais permet notamment d'ajouter de nouvelles méthodes de manière à utiliser SIP dans d'autre domaines applicatifs. Les méthodes MESSAGE, PUBLISH et SUBSCRIBE constituent un bon exemple d'extensions ayant trait à des applications qui vont au delà des communications téléphoniques. Dans cette perspective, SIP n'est pas une fin en soi: il n'offre pas fondamentalement plus de services qu'un espace de communication au sein duquel des utilisateurs peuvent se trouver et communiquer, appuyé d'un modèle décrivant comment un échange de messages (une ou plusieurs transactions) doit s'opérer entre deux entités. Il en découle que l'on peut considérer SIP comme un meta-protocole dans le sens où il permet de créer un ensemble de protocoles plus spécifiques avec une sémantique particulière. On pourrait donc considérer à ce titre une application SIP comme une particularisation du protocole SIP au moyen d'un ensemble de méthodes, exprimant une sémantique liée à un domaine particulier, comme par exemple 15 Conception et réalisation d'une plateforme applicative pour le protocole SIP la communication à distance entre programme, ou encore la coordination de tâches à effectuer entre différentes entités. Des applications principalement réactives De par son aspect généraliste, il est difficile de prédire quelles seront les applications du protocole SIP. Les plus naturelles sont évidemment celles des services de la téléphonie classique [33], et de la conférence [36], mais comme nous l'avons dit, la nature extensible de ce protocole lui permet de trouver des applications en dehors de ce cadre. Face à la difficulté de prédire [37] les applications du protocole SIP, nous ne pouvons qu'essayer d'en deviner les caractéristiques principales. Pour ce faire, il faut s'interroger sur la nature des services qui pourraient être attendus de ce type d'applications. Tout d'abord, on remarque que SIP est utilisable actuellement pour coordonner différents flux d'information: on initie une session qui va définir un ensemble de canaux (par exemple voix, vidéo, messages instantanés) par lesquels deux UA vont communiquer. Chaque UA doit donc mettre en place et contrôler ces canaux de communication. Lorsqu'un UA voudra interrompre la session, il devra interrompre les communications en cours pour chacun des canaux utilisés. Ainsi l'application qui fournira le service permettant de communiquer en utilisant la voix, la vidéo et la messagerie instantanée au travers de SIP devra gérer autant de protocoles qu'il y a de canaux différents, mais surtout un nombre tout aussi important d'évènements, pouvant parfois survenir simultanément. En effet, l'application SIP correspondant à l'UA devra être en permanence à l'écoute des différents évènements qui peuvent se produire sur les canaux utilisés pour la communication, et réagir en conséquence. Le cas que nous citons est parmi les plus simples: celui d'un agent utilisateur tel qu'un téléphone SIP logiciel ; des applications plus complexes, telles que notamment la gestion de conférence sont donc susceptibles d'impliquer un nombre plus grand d'évènements à gérer. Le fait que les applications SIP impliquent d'être à l'écoute d'évènements, et d'être prêts à y réagir nous permet de poser que les applications SIP sont principalement de nature réactive [27]. Une concurrence à deux niveaux En reprenant notre exemple d'UA SIP, nous constaterons que la notion de réactivité à des évènements provenant de sources diverses (la canal de son, le canal vidéo, la messagerie instantanée, et bien sûr SIP lui-même) implique de pouvoir effectuer plusieurs tâches simultanément. En effet, l'UA doit toujours être capable de percevoir un évènement (comme une erreur réseau), alors même qu'il en traite un autre (par exemple, le changement de paramètres du canal de voix). Il y a donc une notion de concurrence interne à un UA, car celle-ci s'effectue au sein même des processus animant l'agent. Lorsque l'on sort du cadre d'une application servant principalement de client, pour se diriger vers des catégories d'applications offrant un service à un plus large ensemble d'UA (tel que la gestion et le déroulement d'une conférence), autrement dit des serveurs, on peut considérer un second niveau de concurrence. En effet, en dehors du contexte d'une transaction SIP, englobant elle-même un ensemble de transactions liées aux flots de communication, une application fournissant un service SIP (un serveur 16 Conception et réalisation d'une plateforme applicative pour le protocole SIP SIP) doit pouvoir répondre à nombre de clients, avec le moins de latence possible. La concurrence externe est donc le fait de pouvoir fournir le même service (ou différents services) à un ensemble de clients. Ainsi en considérant à la fois la concurrence nécessaire à la réalisation d'un service pour un UA donné, et la concurrence nécessaire à la mise à disposition de ce service à un ensemble d'UA, nous pouvons poser que les applications SIP sont également de nature concurrente, ceci allant par ailleurs de paire avec leur nature réactive. Des sessions d'une durée importante La plupart des protocoles de communication basés sur un modèle transactionnel, comme c'est le cas pour le protocole HTTP [30] présentent un mécanisme d'échange relativement simple, et de durée prévisible. Ces échanges, réalisés par des transactions entre deux UA, éventuellement à la fois clients et serveurs, constituent ce que l'on appelle des sessions. En pratique, une session regroupe un ensemble de transactions réparties dans le temps, avec éventuellement des périodes d'inactivité. De ce point de vue, les applications SIP fournissant des services complexes, à l'image des sites de commerce électronique suivant un acheteur parcourant la boutique en ligne, auront sûrement besoin de représenter et gérer des sessions dont la durée peut aller de quelques minutes à plusieurs heures, comme ce peut être la cas pour une conférence. 2.2.2. Logiciels existants L'engouement pour le protocole SIP, et les possibilités qu'il représente pour le monde de la téléphonie a résulté en une pléthore de logiciels disponibles [38]. Ces logiciels vont de la «pile» SIP pour les langages C ou C++ au serveur d'application complet en C++ ou en Java. En établir une liste et en détailler les fonctionnalités est un travail conséquent sortant du cadre de ce document. En effet, nous considérons uniquement un sous-ensemble de logiciels libres [8] relatifs au protocole SIP. Les logiciels libres disponibles A l'opposé des logiciels commerciaux, il existe un petit nombre de logiciels libres consacrés à SIP. A l'heure actuelle (printemps 2003), il existe principalement les logiciels suivants, classés par catégories: ­ ­ Piles SIP GNU oSIP, écrite en C, dissipate écrite en C++, et Jain écrite en Java. UA SIP kphone, un client SIP pour KDE utilisant `dissipate', et linphone, un client SIP pour Gnome utilisant oSIP. Routeur/Serveurs SIP SER (SIP Express Router) qui est une plateforme flexible de routage SIP, Vovida une solution complète de communication par SIP, partysip qui est une plateforme pour la réalisation d'applications SIP, basée sur oSIP. ­ 17 Conception et réalisation d'une plateforme applicative pour le protocole SIP Des trois routeurs/serveurs SIP disponibles, seul SER est à l'heure actuelle une solution envisageable: partysip est très mal documenté, d'une architecture confuse et en perpétuelle évolution, Vovida est extrèmement lourd (près de 140Mo) et difficile à appréhender. Les agents utilisateur SIP que sont kphone et linphone ne représentent qu'un interêt minime par rapport à notre problématique, mais offrent l'avantage de permettre d'effectuer facilement des tests. Ainsi, de tout ces logiciels seuls oSIP et SER représentent un interêt réel pour la problématique qui nous concerne, à savoir la réalisation d'applications SIP permettant de rendre des services complexes, tels que la conférence. Bien que SER soit une application (en fait, un routeur configurable à l'aide d'un langage de script extensible par des modules en C) et oSIP une librairie, il est tout de même possible d'étudier ces deux logiciels dans la perspective de réalisation d'applications SIP complexes qui est la notre. Une analyse préalable [34] a ainsi permis de mettre l'accent sur quelques limitations de SER: ce dernier a été conçu dans une optique de routage (donc de service simple), et non pas pour la réalisation d'applications plus complexes, répondant notamment aux exigences que nous avons proposées plus haut. A ceci s'ajoute une conception architecturale compacte, où il est difficile d'en découpler les composantes. Ceci en rend l'adaptation plutôt difficile, et limite les possibilité d'extraire des parties pour les réutiliser dans d'autres applications. GNU oSIP, en qualité de librairie, est abstraite de toute spécialisation qui nuirait à sa flexibilité cette librairie est en fait conçue pour épouser de manière fidèle les spécifications du protocole SIP [31] émises par l'IETF. Elle n'offre par contre absolument pas toutes les fonctionnalités permises par SER, qui au titre d'application permet dès le départ d'effectuer bien plus de choses. Comme dans la plupart des cas, la facilité d'accès de SER se paie par une difficulité à réaliser des applications pour lesquelles il n'a pas été prévu, alors qu'oSIP n'est pas conçu pour un type d'application particulier et offre donc une base adaptée à un large panel d'applications. Une approche conventionnelle Que ce soit dans le domaine commercial ou le domaine applicatif, on notera un certain manque de recul par rapport au protocole SIP: les logiciels se bornent à une implantation fidèle de la spécification, lorsqu'il s'agit de piles SIP, et à une intégration du protocole au sein d'architecture déjà existantes pour les serveurs. L'approche par rapport à SIP est plutôt d'intégrer SIP à l'existant, et non pas d'adapter l'existant à SIP. Il va sans dire que l'existant n'est pas vraiment adapté aux évolutions que connaissent les exigences des applications actuelles, que nous avons mentionné précédemment. On prendra notamment comme exemple les efforts de Sun [14] et de Microsoft pour intégrer SIP au sein de leur plateformes respectives (Java et.NET), ou bien encore SER qui a construit son serveur SIP dans le plus pur style des daemons Unix. Aucune n'apporte une véritable reflexion sur les exigences liées à la conception d'applications basées sur le protocole SIP. De manière générale, l'intégration d'un protocole dans une architecture a un impact relativement faible sur celle-ci, et limite parfois les perspectives offertes par le protocole en le ramenant vers le paradigme existant. Il est par contre intéressant d'étendre l'architecture pour qu'elle s'intègre dans l'architecture globale crée par le protocole (le réseau d'agents SIP), d'autant plus que l'utilisation d'un protocole ne 18 Conception et réalisation d'une plateforme applicative pour le protocole SIP requiert pas un couplage très fort entre les agents utilisateur et l'implantation du protocole (la pile SIP) ce qui facilite cette intégration. 2.2.3. Domaines de recherche Nous avons présenté précédemment notre perspective d'applications complexes basées sur le protocole SIP, ainsi que les exigences qui en découlent. Dans ce contexte, nous avons abouti aux propositions suivantes: ­ Les applications SIP sont principalement réactives Un agent SIP doit réagir à un ensemble d'évènements en provenance de différents canaux, utilisant éventuellement des protocoles différents. Les applications SIP sont fortement concurrentes Que se soit au niveau d'une application simple où un agent ne doit pas être bloqué dans sa perception de nouveaux évènements lorsqu'il réagit à un autre, ou au niveau d'une application complexe où une il faut fournir un service à un nombre important d'agent. Des transactions d'une durée longue Un ensemble de communications fait partie d'une session initiée et contrôlée au moyen du protocole SIP, une application complexe doit donc représenter et gérer cet ensemble de communication sur une durée allant de quelques minutes à plusieurs heures. ­ ­ Ces caractéristiques sont par ailleurs cohérentes avec l'évolution générale des besoins dans la réalisation d'applications dans le contexte technologique actuel [39], où l'on demande sans cesse plus d'interoperabilité et d'interaction entre différentes applications, de même qu'une disponibilité toujours plus grande. La programmation réactive La première caractéristique des applications de communication, et en particulier des applications SIP (selon nos hypothèses) est de réagir à un ensemble d'évènements. Cette problématique a été traitée dans le cadre de ce que l'on appelle la programmation réactive [27]. Parmi les courants principaux, on notera deux approches différentes: ­ Une approche issue de la programmation orientée objet: développée notamment au sein du projet MIMOSA [17], elle vise à mettre en place une infrastructure favorable au développement d'applications réactives [5] au sein de langages tels que Scheme ou Java. Une approche issue de la programmation fonctionnelle: plus formelle que l'approche objet, l'approche fonctionnelle (appelée FRP (Functional Reactive Programming) en anglais) tend à proposer des langages ayant une sémantique clairement définie [7] et adaptée à la réalisation d'applications réactives. ­ Ces deux approches sont tout à fait complémentaires: alors que la première se focalise plus sur la création de cadres/librairies adaptées à la programmation réactive en proposant une infrastructure directement utilisable avec les langages actuels pratiqués dans l'industrie, la seconde explore la spécialisation/extension de langages existants ou la création de langages dédiés à la programmation 19 Conception et réalisation d'une plateforme applicative pour le protocole SIP réactive, offrant des avantages notamment en ce qui concerne la modélisation, la spécification et la validation de programmes. De manière similaire, la première approche met l'accent sur les aspects techniques, pratiques de la réalisation d'applications réactives, alors que la seconde insiste plutôt sur les aspects sémantiques, plus théoriques. La mise en avant des aspects techniques de la réalisation d'applications réactives met toutefois le doigt sur les problèmes liés à la concurrence: une application réactive doit pouvoir réagir à un évènement même quand elle est en train de réagir à un autre. Une approche théorique ne permet pas vraiment d'éclairer cette problèmatique, qui découle principalement des caractéristiques des systèmes d'exploitation actuellement utilisés. De la programmation réactive à la programmation concurrente Les problèmes liés à la concurrence sont de plus en plus couramment rencontrés par les développeurs, l'utilisation de processus lourds (processus Unix) ou légers (threads) s'étant largement généralisée. Rappelons que le problème principal de la concurrence vient du fait qu'une fonction peut être interrompue dans son exécution à n'importe quel moment par le système d'exploitation (ou la machine virtuelle), et que pendant cette interruption, des données utilisées par cette fonction pourront être modifiée. En ce sens, la programmation fonctionnelle, et notamment la programmation fonctionnelle pure protègent les développeurs de cette problématique de par leur nature (par exemple, le langage Haskell [11] est très utilisé en programmation réactive fonctionnelle). En effet, l'absence d'effets de bord permet de garantir l'intégrité des valeurs manipulée, et dissocie de fait les problématiques de la programmation réactive de celle de la programmation concurrente. Pourtant, un langage fonctionnel n'est pas forcément nécessaire. On prendra pour exemple le langage Erlang [4] qui déclare toutes ces variables comme étant immuables et assignables une seule fois, ce qui empêche les effets de bords, sans imposer toutefois un style fonctionnel (le style d'Erlang mélange expressions déclaratives et impératives). A ce problème de développement, qui engendre bien souvent un nombre impressionnant de problèmes et de temps perdu avec les langages pratiqués le plus couramment (C, C++, Java), s'ajoute également une performance moyenne lors d'une charge importante du système. Cet aspect a notamment été illustré dans des implantations de serveur HTTP selon différents modèles d'exécution [12]. En effet, lorsqu'il y a un nombre important d'entités concurrentes à gérer, le système perd en général de plus en plus de temps et de ressources dans la gestion de ces entités. On trouve ainsi dans les patrons de conception Réacteur [28] et Proacteur [25] des propositions de solutions à la réalisation d'applications réactives concurrente. Chacun propose des modèles pour le traitement synchrone ou asynchrone d'évènements, essayant de proposer une approche de la concurrence qui limite les pertes de performance rencontrées avec les approches classiques (héritées de la programmation multi-processus de style Unix). Les langages acteurs et systèmes d'agents 20 Conception et réalisation d'une plateforme applicative pour le protocole SIP Les problématiques liées aux applications réactives et à la programmation concurrente (et en générale également distribuée) ont été entre autres développées il y a plus d'une dizaine d'années dans le contexte des langages acteurs proposé par Gul Agha, dont on peut apprécier les récentes réalisations avec le langage Salsa [32]. C'est à la même période que l'on voit apparaître des travaux relatifs aux systèmes d'agents (ou systèmes multi-agents, terme quelque peu redondant). Pour Gul Agha, le modèle des acteurs est une encapsulation d'un état (données) et d'un flux de contrôle manipulant cet état, la communication entre les acteurs s'effectue par échange de message. Si l'on se réfère à deux définitions de l'objet, la première étant l'encapsulation de données et l'agrégation des opérations pour manipuler ces données dans une même entité, la seconde (plus large) étant des entités communiquant par échange de message, on remarque clairement que la seule différence entre un acteur et un objet est la prise en compte de la notion de flux de contrôle, que l'on peut appeler la caractéristique d'exécution, d'activité ou d'autonomie. Les acteurs sont donc en fait un autre nom pour des objets actifs. Bien qu'il existe beaucoup de définitions des agents, il semble que l'intérêt qui leur est porté depuis plusieurs annéees ait permis à celles-ci de se stabiliser. Ainsi dans son panorama [2] du génie logiciel orienté agent, Amund Tveit présente les agents comme étant similaires aux objets, mais supportant des structures permettant la représentation d'états mentaux, de croyances (etc) et des mécanismes de communications par messages plus évolués que les mécanismes ad-hoc proposés par les objets. Il note également qu'un des aspect importants des agents est leur autonomie, par opposition à la passivité des objets, qui ne s'activent pas seuls. Cette dernière définition, certes un peu large, ne peut que nous conduire à penser qu'acteurs, agents, et objets actifs sont un seul et même concept. Ainsi, comme le disait Michael Fischer [6] en 1994 "un système multi-agent est simplement un système constitué d'objets en exécution concurrente" ; en effet, il nous semble inutile de considérer qu'un agent a forcément des connaissances ou des croyances, ou qu'il échange des messages selon la théorie des"actes de langage" ce sont la des aspects spécifiques à une approche agent particulière, tout comme il existe différentes approches de l'objet (comme par exemple les langages utilisant des classes ou des prototypes pour réaliser des concepts d'héritage). Etant donné les exigences liées à notre problématique, les langages d'acteurs et les systèmes d'agents représentent des thèmes au sein desquels nous pourrons nourrir notre proposition, notamment par l'importance qu'ils accordent à la notion d'autonomie. Les langages de scripts et les langages de domaine Un langage de programmation est avant tout un outil permettant d'exprimer un ensemble d'éléments qui mis ensemble constituent une application. En ce sens, le langage joue un rôle essentiel, car c'est lui qui fournit le cadre concret dans lequel va se faire le développement, et par conséquent également une partie de l'analyse et la conception. L'utilisation de langages spécifiques, ou l'extension de langages existants, dans le but de faciliter l'expression de programmes spécifiques à un domaine permet de réduire le fossé qui sépare les spécifications de l'implantation: lorsqu'un langage est suffisamment expressif, il devient possible de déduire l'implantation des spécifications, quand le programme lui-même n'est pas considérable comme une spécification. 21 Conception et réalisation d'une plateforme applicative pour le protocole SIP De même l'utilisation de langages de scripts pour la conception d'applications a pour avantage, au coût de quelques ressources mémoire et processeur, de permettre un prototypage rapide des applications et une liaison aisée entre différentes composantes d'une application. Il est malheureusemet difficile de trouver des articles traitant de l'impact des langages sur le développement, mais certains blogs, tels que le fameux Lambda The Ultimate [16] abordent régulièrement cette question. Il est clair que le nombre croissant de langages existant et pratiqués, de même que la généralisation de l'utilisation de langages de scripts est un facteur favorable à une réflexion en profondeur sur le rôle qu'ont les langages dans notre manière d'envisager les problèmatiques qui se présentent à nous. Récapitulatif La figure 2 récapitule les différents domaines ainsi que les besoins qui les lient, il a pour but de représenter les liens reliant les différents domaines informatiques que nous avons abordé jusqu'à présent. 0 1 2 )3 # / 2 4 5 (, /% ) !"#$%&'( )'*+,'**$&'* ! 2 (' $ 0 2 6 % 6 ,' ! " # # $ % & ' ( )& " % ;'("'46/( *6%+'%4/(6%%','%2 - . 7 6 % ) (' + 3 )'*+.45%','%2* !2('+)."(/2 * + " , + ( # # ( )& " % ' " % ' $ + + / % )/ 6 (% , (, /2 4 /7 4 " #(& % / -.$&/(+*/,012$%.,'%2 3+)'*+.45%','%2* 8'9%/( *$+*.,$2/:0' * + " , + ( # # ( )& " % + - ( ' )& . / Figure 2. Le graphe des besoins reliant les domaines Ainsi, le protocole SIP est un protocole de communication impliquant d'utiliser un ensemble d'autres protocoles, ce qui nous place véritablement au coeur du domaine de la communication. Les 22 Conception et réalisation d'une plateforme applicative pour le protocole SIP problématiques de ce domaine nécessitent de répondre à des évènements liés au différents canaux de communication (par exemple, l'arrivée de nouvelles informations, ou la rupture du flux de communication), ce qui est traité par la programmation réactive. Cette dernière quand à elle, implique de pouvoir répondre à plusieurs évènements simultanément, ce qui nous amène au domaine de la programmation concurrente. En considérant le domaine des systèmes d'agents, on remarque qu'il est lié au domaine de la communication par le besoin d'échanger des messages, au domaine de la programmation réactive par le besoin de percevoir son environnement (et donc d'y réagir), et également au domaine de la programmation concurrente par son besoin d'autonomie. Un système agent devant être décrit, et plus particulièrement les interactions entre les agents, nous arrivons au domaine des langages de domaine. Ici, le langage de domaine a un besoin d'identifier la sémantique de son domaine, principalement basée sur les concepts de la programmation réactive. 2.3. Proposition Nous venons de voir qu'une utilisation poussée du protocole SIP, résolument orientée vers les évolutions pressenties de son cadre applicatif implique la prise en compte des problème liés à la réaction par rapport à des évènements, à la concurrence, et à la description de comportements réactifs. Nous avons également vu que ces problèmes sont abordés dans des domaines de recherches tels que la programmation réactive et la programmation orientée agent, croisant également la conception de langages de scripts ou de domaine. L'objectif de réaliser une «plateforme pour applications SIP» est un objectif vaste et relativement mal défini. De ce fait, et comme nous l'avons présenté lors de l'analyse, il est important de baser notre proposition sur des besoins d'extensibilité et d'évolutivité. Nous allons développer ici notre approche de la conception d'une plateforme SIP, et proposer une décomposition de la plateforme représentant celle-ci. 2.3.1. Approche Nous avons décrit les liens qui unissent les problématiques de la programmation réactive aux problématiques de la programmation concurrente, et la manière dont les systèmes d'agents apportent un cadre favorable à la résolution de celles-ci. Notre approche se base sur l'intégration de ces différents domaines au sein d'une seule et même plateforme. Une plateforme agent étendue Nous posons l'hypothèse que la réalisation d'une plateforme pour des applications SIP, des UA SIP, des serveurs proxy, jusqu'aux applications plus complexes telles que le gestion de la conférence, peut en fait se généraliser à la réalisation d'une plateforme permettant le développement d'applications réactives et concurrentes, étendue pour offrir l'infrastructure nécessaire à la communication par le protocole SIP, ainsi qu'un ensemble d'abstractions facilitant l'expression de telles applications. En effet, considérons les caractéristiques suivantes, concernant les agents: ­ Autonomie 23 Conception et réalisation d'une plateforme applicative pour le protocole SIP Les agents peuvent agir par eux-mêmes, indépendamment d'une stimulation extérieure. ­ ­ Communicants Les agents communiquent entre eux par échange de message. Contextualisés Les agents sont contextualisés dans un environnement avec lequel ils peuvent interagir, en percevant des évènements ou en explorant l'environnement. On remarque déjà que la notion d'autonomie s'accorde bien avec les besoins de concurrence, et que la communication par messages ou par évènements semble également un cadre adapté à la programmation réactive. Par rapport à l'objet, l'agent offre des caractéristiques plus spécifiques lui permettant de réagir à son environnement (d'être réactif ) et également d'agir de lui-même (son autonomie). La notion de concurrence est ici implicite. SIP intégré comme un langage de communication externe Une caractéristique également remarquable est le fait que les agents communiquent par message. En effet, la plateforme ne définit pas forcément la qualité de messages échangés: un message peut être réduit à un appel de méthode (c'est le cas du modèle objet proposé par le langage SmallTalk), ou bien peut contenir des informations plus riches (envoyeur, indice, priorité, date, attributs), et éventuellement nécessiter un traitement (parsing). Cette abstraction par rapport aux messages nous permet d'intégrer SIP à cette architecture: il est concevable que la communication entre agents s'opère au moyen du protocole SIP. L'avantage principal étant que les messages SIP font dès lors partie d'une architecture généraliste, et peuvent donc profiter des fonctionnalités offertes au sein de celles-ci (traitement, transport, archivage, ordonnancement, etc). En ce sens, Charles Petrie propose d'utiliser plusieurs langages [21] au sein d'applications orientées-agent: un langage interne décrivant la communication entre les agents internes à l'application, et un langage externe servant d'interface entre des agents d'applications différentes. Charles Petrie entend par sa notion de langage le format et la sémantique des messages échangés selon sa perspective, SIP peut-être considéré comme un langage, mais comme peut l'être également le mécanisme d'invocation de méthodes sur un objet. Ainsi, Charles Petrie entend utiliser des messages simples, comme des appels de méthodes, pour la communication interne (ce qui accélère l'exécution de l'application), et d'utiliser des messages plus complexes pouvant nécessiter une interprétation (parsing) lors de la communication externe. En effet, la communication interne peut-être réalisée avec un couplage fort (les échanges de messages, ou appels de méthodes sont contraints par le compilateur), ce qui apporte fiabilité plus grande (contrôle des types) et une plus grande vitesse (échanges n'impliquant qu'un minimum de traitement supplémentaires lors de l'exécution), alors que les échanges entre le système et l'extérieur, moins sûrs, peuvent profiter d'un couplage lâche, où le message est interprété, et nécessite donc plus de temps et de ressources. Un modèle d'application 24 Conception et réalisation d'une plateforme applicative pour le protocole SIP Une application pourra donc utiliser SIP comme langage de communication externe (mais également interne, car rien ne l'empêche), et considérer son interface de programmation (API) comme le langage interne entre les agents (à la condition que le langage d'implantation considère l'invocation d'une méthode comme l'envoi d'un message à un objet). Cette approche permet d'entrevoir le modèle d'applications SIP proposé dans la figure 3, où une application est composée d'un ensemble d'agents interagissant au moyen de l'API interne, dont certains s'interfacent avec des entités externes (programmes, serveurs, autres agents) au moyens d'autres langages/protocoles, tels que SQL ou bien évidemment le protocole SIP. & $% '% ( )*+ ! "#$% #,%(-'#.- / 00 1+ 2 )*+ )34 !"#$%56#,%#-$#5 ! "#$% !+* ! "#$% !+* !"#$%56'$%#-$#5 !+* ! "#$% ! "#$% Figure 3. Un modèle applicatif possible pour les applications SIP Ce modèle offre l'avantage d'une décomposition nette, par flux de communication, en plus des avantages inhérents à la programmation orientée agent, comme notamment l'évolutivité (possibilité de facilement rajouter des agents au système) et la flexibilité (possibilité d'ajouter ou de supprimer à tout moment des agents qui ne seraient pas nécessaires). La décomposition par flux (certains agents sont chargés de traiter un flux de communication et de prendre/intégrer les informations dans le reste du système) permet d'isoler les fonctionnalités, et par conséquent d'alléger la conception et de faciliter la résolution des problèmes qui sont de fait mieux localisés. L'aspect autonome des agents garantit également la réactivité par rapport à l'ensemble des flux. Notons toutefois qu'un agent peut très bien être décomposé en un ensemble de sous-tâches, qui peuvent elles-mêmes être incarnées par des agents. Ce modèle est simplement un patron de conception proposant une solution à la réalisation d'applications SIP sur une plateforme agent. Un langage de domaine adapté à la communication Le contexte de la programmation réactive a donné lieu à la conception de nombreux langages conçus dans le but d'intégrer deux aspects majeurs des systèmes réactifs: la description de la structure 25 Conception et réalisation d'une plateforme applicative pour le protocole SIP et le comportement dynamique. Le langage ProFun [26] propose de ce fait de séparer descriptions structurelle et comportementale à l'aide de deux langages différents faiblement liés entre eux. La description de structure est quelque chose que nous savons actuellement très bien faire avec les langages orientés-objet, qui ont été principalement conçus dans ce but. Par contre, la description de comportements est plus difficile avec les langages impératifs que nous avons l'habitude d'utiliser. En effet, considérons le filtrage d'un évènement sur un mode impératif: // On boucle en prenant séquentiellement chaque évènement qui arrive // et on sort de cette boucle lorsqu'il n'y a plus d'évènement while ( event = waitForNextEvent() ) { if ( event.getType() == MouseEventType ) { ... } else if ( event.getType() == TimerEventType ) { ... } ... } Exemple 2 Filtrage d'un évènement sur le mode impératif On voit qu'il est nécessaire lorsque l'on veut traiter un autre type d'évènement de rajouter une condition à cette série de test. Il est à noter par ailleurs que ce mode est éminemment séquentiel, ce qui pose donc des problèmes de concurrence: il vaut mieux que le corps des blocs rattachés aux conditions n'effectuent pas d'appels bloquants. on ( MouseEventType ) { ... } on ( TimerEventType ) { ... } // On traite tous les évènements qui arrivent, en utilisant // les réactions décrites ci-dessus handleEvents(); 26 Conception et réalisation d'une plateforme applicative pour le protocole SIP Exemple 3 Filtrage d'un évènement sur le mode déclaratif/impératif Ici, l'ajout d'une simple primitive on() ayant pour sémantique la déclaration d'une réaction par rapport à un type d'évènement paraît plus simple, tout en offrant l'avantage d'abstraire la manière dont sont traités les évènements: plutôt de dire comment les évènements sont filtrés, on se limite à dire lesquels. Le langage doit donc offrir une infrastructure qui sous-tend les primitives on() et handleEvents(). Une utilisation de primitives déclaratives au sein d'un langage impératif permet en effet de s'abstraire du flot de contrôle en déclarant des opérations qui seront (en général) exécutées de manière asynchrone, à un moment différé par rapport à leur déclaration. L'idée d'utiliser un langage déclaratif est également abordée dans l'article "Toward Interaction-Oriented Programming" [35] de Munindar P.Singh, où il reprend de [24] que bien que les patrons de conception (design patterns) attirent beaucoup d'attention dans le cadre de la programmation orientée-objet, elles ne sont pas formalisées1 et se focalisent plus sur la structure d'un programme que sur ses interactions. L'utilisation d'un langage spécifique pour la description des comportements (par opposition à la structure) dans un système réactif permet à la fois de faciliter l'expression de ces comportements, en offrant des primitives et des constructs adaptés, mais également de placer le développeur dans un contexte favorable à la conception de systèmes réactifs sans ce langage, il aurait sans doute plus de mal à considérer les problématiques sous l'angle le plus abordable. Ainsi, on trouve quasi-systématiquement dans les langages réactifs les notions d'évènement et de comportement, généralement représentées par des primitives ou des types de base dans le langage. 2.3.2. Décomposition Nous venons de voir que l'approche avec laquelle nous proposons de réaliser une plateforme pour des applications SIP s'oriente sur les points suivants: ­ ­ ­ L'utilisation ou la création d'une plateforme agent étendue L'intégration de SIP en tant qu'un autre langage de communication entre agents dans cette plateforme La création ou l'extension d'un langage afin d'en faire un langage de domaine adapté à la programmation de comportements. Ces différents points entraînent une décomposition de la réalisation de la plateforme suivant la même organisation. Le détail de cette décomposition est explicité ci-dessous. Le choix d'un modèle et d'une plateforme agent L'étape fondamentale de la réalisation de la plateforme est de choisir (ou de créer) une plateforme agent adaptée aux problématiques que nous avons exprimées. En fait, il serait trop complexe de 1 Un aspect généralement présent dans la programmation fonctionnelle réactive, ainsi que le langage proposé par Munindar 27 Conception et réalisation d'une plateforme applicative pour le protocole SIP créer une plateforme agent depuis le début, il est donc préférable de ne considérer que le choix d'une plateforme adaptée aux besoins. Pour ce faire, l'accent doit être mis sur la réalisation des caractéristiques des agents énoncées précédemment (autonomie, communication et évolution dans un environnement), mais également sur les aspects techniques de la plateforme, comme la performance, le langage d'implantation et la possibilité d'adapter l'existant. L'intégration de SIP dans la plateforme Une fois la plateforme agent choisie, il est possible de déterminer de quelle manière le protocole SIP peut être intégré dans celle-ci. Pour ce faire, il faut avant tout choisir une implantation du protocole SIP (communément appelé une pile SIP) pouvant être utilisée conjointement avec la plateforme. Une attention particulière doit être portée à cette pile SIP, car elle doit offrir un niveau suffisant de détail par rapport au protocole SIP (ne pas être trop abstraite), tout en restant généraliste et flexible. Un problème important est la possibilité d'adapter la pile au modèle d'exécution de la plateforme hôte (mono-processus, multi-processus ou multi-tâches). Une fois la pile SIP choisie, il s'agit d'enrober (wrapping en anglais) celle-ci de manière à être adaptée dans son interface de programmation au langage et à la plateforme hôte. Cet enrobage doit également offrir des facilités permettant différents niveaux d'abstraction pour l'utilisation du protocole SIP, de manière à en simplifier l'utilisation, encore une fois, sans empêcher pour autant l'accès aux mécanismes de bas-niveaux. Enfin l'intégration de la pile SIP au sein de la plateforme doit permettre aux agents de communiquer en échangeant des messages SIP. La manière dont cette intégration peut être faite dépend entièrement du modèle de communication proposé par la plateforme. La création d'un langage de domaine Les deux étapes précédentes suffisent à offrir une plateforme de base permettant de réaliser des applications SIP orientées-agent, et par conséquent offrant un contexte favorable à la résolution des problématiques du domaine. Afin de faciliter le développement d'applications SIP, et de manière à s'abstraire, au moins partiellement, du langage hôte, la dernière étape est de mettre au point un langage adapté au domaine que constitue le développement d'applications SIP. Tout d'abord, il est généralement plus pratique de choisir un langage déjà existant, et de tenter de l'étendre syntaxiquement et/ou sémantiquement pour qu'il offre les abstractions spécifiques au domaine, plutôt que de réaliser le langage soi-même. La première étape est donc de choisir le langage qui pourrait être utilisé comme base pour le langage de domaine, en tenant compte du fait que ce langage devra pouvoir communiquer avec la plateforme hôte, et de son extensibilité. Les langage de scripts embarquables sont à ce titre d'excellents candidats. Ensuite, il s'agit de définir les concepts qui poseront la sémantique du langage de domaine. Cette étape est extrêmement importante, car elle constitue un effort important d'analyse afin d'extraire les aspects fondamentaux du domaine. 28 Conception et réalisation d'une plateforme applicative pour le protocole SIP L'identification de ces concepts permet dès lors de poser un ensemble de primitives et de constructs servant de base à la réalisation du langage de domaine. Cet aspect implique de tenir compte de l'aspect syntaxique et de faciliter au maximum la clarté et la simplicité du code. Enfin, l'ajout de simplifications syntaxiques, éventuellement d'une interface de programmation, permet encore d'améliorer l'ergonomie du langage de domaine. Cette étape est suivie par l'intégration finale du langage de domaine dans la plateforme hôte. 2.3.3. Synthèse Le schéma suivant résume les différentes étapes ainsi que les contraintes importantes associées à chacune. On observe notamment que les choix initiaux, notamment le langage dans lequel est écrit la plateforme, vont avoir une influence sur les choix suivants. 29 Conception et réalisation d'une plateforme applicative pour le protocole SIP 3. Réalisation Nous avons présenté le protocole SIP, son contexte, et au regard d'une analyse des caractéristiques des applications SIP nous avons établi une proposition de plateforme pour applications SIP. La présente section a pour but de détailler la manière dont cette plateforme a été réalisée, conformément à la décomposition proposée. Ainsi nous verrons tout d'abord le choix de la plateforme agent sur laquelle notre projet se base, ensuite nous verrons la manière dont nous intégrons le protocole SIP au sein de cette plateforme, enfin nous aborderons le langage de domaine permettant de réaliser plus facilement des applications basée sur SIP. Chaque partie est décomposée selon une approche où l'on étudie les besoins et les problèmes possible avant d'aborder la réalisation proporement dite. Par ailleurs, l'aspect organisationnel du projet est également important, c'est en l'occurence le propos de la section suivante. 3.1. Organisation L'étape préliminaire d'organisation permet de préparer la réalisation de la plateforme. Les contraintes techniques et de conception sont établies durant cette étape, un modèle de développement est posé, des outils et un planning initial sont également proposés. Cette approche permet d'obtenir un modèle sur lequel la réalisation du projet peut se dérouler ce modèle n'est pas à prendre comme un impératif, mais plutôt comme un guide qui doit lui aussi s'adapter aux évolutions de la réalisation. 3.1.1. Contraintes La réalisation d'un projet informatique implique de faire des choix techniques. Ces choix techniques doivent tenir compte à la fois des besoins exprimés lors de l'analyse et de l'environnement cible. Dans le contexte de ce projet, l'environnement cible est un système Linux récent (noyau 2.4), sans contrainte de ressources CPU et de mémoire. Il n'y a pas non plus de contrainte imposée pour le langage ou les librairies à utiliser. Par contre, il est important que les logiciels utilisés dans ce projet soient des logiciels libres, le projet lui-même peut par conséquent, dans le cas d'utilisation de logiciels en License Publique GNU [10]), être un logiciel libre. Les contraintes techniques sont donc purement et simplement de pouvoir compiler et exécuter le programme sous Linux, et éventuellement d'autres variantes de Unix. Ainsi, il est possible d'effectuer nos choix de manière relativement libre, en accord avec les besoins relatifs à la problématique, et non pas à l'environnement matériel et logiciel ce qui est une situation plutôt appréciable. Par ailleurs, ce projet étant un projet de recherche, il n'y a pas d'existant à reprendre ou a intégrer. Néanmoins, la plupart des applications existantes étant écrites en C ou en C++, il serait appréciable que la plateforme s'intègre bien avec ces langages. Il n'y a pas non plus de critères spécifique de performance ou de compacité, néanmoins il serait appréciable que la plateforme ainsi que les applications prennent une taille raisonnable en mémoire (moins de 10Mo) et tournent sur de petites configurations1, comme par exemple un Pentium 200Mhz 1 Ces contraintes sont liées aux configurations bas de gamme des produits Alcatel qui pourraient être concernés par notre plateforme 30 Conception et réalisation d'une plateforme applicative pour le protocole SIP avec 32Mo de mémoire. Cette configuration minimale est l'équivalent de certains des produits qui pourraient être interressés par la plateforme que nous développons. En résumé, les contraintes sont les suivantes: · · · · · Développement pour Linux 2.4 et supérieur Pentium 200Mhz, 32Mo comme plateforme cible Intégration avec C/C++ appreciée Moins de 10Mo en mémoire pour la plateforme et une application Travailler de préférence avec des logiciels libres 3.1.2. Modèle de développement Nous basons notre approche méthodologique du développement de la plateforme sur les méthodes Rational Unified Process et eXtreme Programming. Notre approche n'est pas dogmatique, mais consiste plutôt à respecter les lignes directrices de ces méthodes, tout en les interprétant pour les adapter au contexte de notre plateforme. Ainsi, ce projet étant un projet de recherche, il ne répond pas à des besoins spécifiques, ou à un besoin exprimé par une application concrète. Il nécessite un bon nombre d'essais et d'erreurs, qui devraient aboutir sur un prototype représentatif. Il n'y a par ailleurs aucune installation (déploiment) à effectuer. Dans ce contexte, le projet a les caractéristique suivantes: ­ ­ ­ ­ Fort besoin de prototypage Pas de besoin ou d'application particulière Pas de spécifications disponibles Pas de déploiement Par conséquent, les besoins et les solutions sont très susceptibles d'évoluer au cours du développement étant donné que ni le domaine, ni les besoins ne sont vraiment compris et exprimés. Dans ce contexte, une approche itérative avec des cycles d'environ 1 mois permet de suffisamment développer un prototype, tout en laissant une marge suffisante pour le remettre en question. Un ensemble de jalons (milestones) sera établi au cours de la réalisation, au fur et à mesure du développement. Bien évidemment, le planning et les fonctionnalités attendues dans chaque jalon évoluent ou sont même redéfinies durant le développement. Les principes essentiels du développement sont les suivants: ­ ­ ­ ­ Réutiliser au maximum les composants existants, à condition qu'ils soient adaptés aux objectifs. Avoir un développement souple avec des cycles courts, permettant de plus facilement remettre en question le travail effectué. Réaliser des suites de tests et des examples de manière à éprouver la plateform, tant au niveau du développement que de la performance. Documenter la plateforme, au niveau du code source, mais également en écrivant de petits documents introductifs. 31 Conception et réalisation d'une plateforme applicative pour le protocole SIP 3.1.3. Infrastructure Ce projet de développement étant principalement un projet individuel, il n'est pas nécessaire de mettre en place une infrastructure de travail collaboratif. Par contre, il est important de se doter d'outils de communication afin de rendre le projet accessible pendant et après son développement. Dans ce contexte, il est utile de produire un site Web du projet (voir figure 4, mettant à disposition les informations suivantes: ­ ­ ­ ­ ­ ­ ­ ­ Présentation du projet, auteurs Activités actuelles du développement Nouvelles concernant l'évolution du projet Détail des différents jalons Versions téléchargables du ou des projets Documentation en ligne, code source en ligne Liste des logiciels utilisés Références bibliographique et Internet Figure 4. Site Web du projet SIP 32 Conception et réalisation d'une plateforme applicative pour le protocole SIP Par ailleurs, il est important de garder une historique des différentes version produites au moyen d'un logiciel de gestion de configuration. En ce qui concerne la documentation, il est important de pouvoir produire de la documentation en ligne (au format HTML), et également une documentation papier de qualité (au format PDF). Les outils choisis pour cette infrastructure sont les suivants: ­ ­ Apache comme serveur HTTP: Installé par défaut et largement connu. Python et le système de templates Cheetah: Syntaxe claire, configuration simple et très rapide. Permet de générer statiquement un site, tout en générant des informations relatives à l'état du projet (derniere version, sources, etc). PRCS: Permet d'effectuer la gestion de configuration de manière souple. PRCS constitue une bonne alternative à CVS, bien qu'il ait le désavantage de ne pas intégrer le support du réseau dans sa version actuelle. SimTex et OrchidéeNoire: Un système d'édition et de production de documentation basé sur une application XML, facilite la création de documents riche en sémantique. Le présent document est rédigé avec ces outils. ­ ­ 3.1.4. Planning Comme nous l'avons déterminé dans l'analyse préliminaire, notre proposition peut se décomposer en trois parties interdépendantes: ­ Le choix d'une plateforme agent détermine le cadre conceptuel et technique (langage utilisé par la plateforme) dans lequel va se dérouler le reste du projet Intégration de SIP au sein de la plateforme choix d'une pile SIP et intégration/amélioration de celle-ci au sein de la plateforme. Ajout d'un langage de domaine permettant de réifier les concepts du protocole SIP et offrant une manière simple et adaptée pour développer des applications pour ce protocole. ­ ­ La durée du projet s'étend sur un peu moins de 6 mois, dont trois semaines sont reservées à la rédaction du présent document. La figure 5 illustre le planning prévisionnel du projet, décomposé en fonction des différentes activités impliquées. 3.2. La plateforme agent La première étape importante dans la réalisation de notre plateforme pour applications SIP est la choix d'une plateforme agent adaptée aux besoins que nous avons exprimés auparavant. Nous allons tout d'abord présenter le rôle de la plateforme agent au sein du projet, son impact, et également les raisons pour lesquelles il est préférable de réutiliser une plateforme existante. 33 Conception et réalisation d'une plateforme applicative pour le protocole SIP 8 !+- 0 5$ 0 ) 6 , 7 &" &3 $ 7 !" # $ %& $ '( $) ? 3 2 , ( &$ 7 , ' F G ' . % $ &$ &9 # , # % $ H 9 ' * -. 9 * # $ %+ ? 3 2 , ( &$ 7 , ' K G ' . % $ &$ &9 # , 0 $ 6 # $ % &, 6 , 7 &" 2 : '(% ? 3 2 , ( &$ 7 , ' I G ' . % $ &$ &9 # , J 2 &% " A , ' 6 , ( ( " A , ( ' * - . , - %. , - %++& / ! " # # $ % &' ( ) % ' * + ! ' , &' $ * - . ! " # # $ % &' 1 , ' ( &" A , / , 0 &) % , ( ' 1 , ' 2 3 4 % , ( ' ( ) % ' * - . 8 7 " 29 ( , ' 1 , ' * + ! 8 7 " 29 ( , 8 7 " 29 ( , ' 1 , ' $ * - . 8 % 0 < 3 &, 0 &) % , ' . 3 % " 7 < " ( E $ * - . : $ 6 # % ; < , 7 ( 3$ 7 ' 1 , ' $ * - . 8 . - ' $ = > , &' # $ ) % ' $ * - . ? $ 1 ; 2 3 ( " &3 $ 7 ' 1 ) ' 1 $ 6 " 3 7 , ' @ 2 " 7 A " A , ' 1 , ' 1 $ 6 " 3 7 , B . % 3 6 3 &3 4 , ( ' , &' $ # ; % " &3 $ 7 ( ' 1 ) ' 2 " 7 A " A , ' 1 , ' 1 $ 6 " 3 7 , 8 % 0 < 3 &, 0 &) % , ' . 3 % " 7 < " ( E - $ 1 $ 2 3& / 4 5 6 1 * +7( / & + . % $ &$ &9 # , ( ' * + ! ' , &' $ * - . . % ; # " % " &3 $ 7 ' 1 , ' . 3 % " 7 < " ( . % $ &$ &9 # , ( ' 3 7 &; A % " &3 $ 7 ' - $ + 7 0 " # ( ) 2 " &3 $ 7 ' 1 , ' $ * - . - 6 # 2 " 7 &" &3 $ 7 - 7 &; A % " &3 $ 7 ' $ * - . ' 1 " 7 ( ' . 3 % " 7 < " ( * # ; 0 3 " 2 3 ( " &3 $ 7 ' 1 , ' - $ - 7 &; A % " &3 $ 7 ' - $ ' 1 " 7 ( ' . 3 % " 7 < " ( - 7 C % " ( &% ) 0 &) % , - 7 ( &" 2 2 " &3 $ 7 * 3 &, ' D , = + 7 4 3 % $ 7 7 , 6 , 7 &' 1 , ' 1 ; 4 , 2 $ # # , 6 , 7 & Figure 5. Planning prévisionnel 3.2.1. Introduction La plateforme agent est l'élément permettant de poser la première pierre au projet. En effet, nous avons proposé d'utiliser une plateforme agent dans le but de se placer dans un contexte propice à la résolution des problématiques liées à la programmation réactive et concurrente. Nous avons montré que le concept d'agent, considéré comme une évolution du concept d'objet intégrant la notion de concurrence, offre un confort conceptuel pour la conception d'applications de communication. Le choix de l'utilisation des agents est également un choix architectural, puisque ceux-ci facilitent la décomposition non seulement des données (statique) mais également des comportements (dynamique). Le rôle de la plateforme agent est de fournir un cadre et des fonctionnalités propices à la réalisation d'agents, ces derniers ayant parfois des propriétés différentes (migration, base de connaissance, etc) en fonction de la plateforme. Par ailleurs, la plateforme agent a un impact important sur plusieurs aspect du projet: Le cadre conceptuel: La plateforme agent va constituer un cadre dans lequel la conception des autres parties du projet va se faire. Par conséquent, la plateforme a une influence directe sur la conception du projet. La langage hôte: La plateforme est réalisée dans un langage (que nous appellerons le «langage hôte»), qui va par conséquent être le langage de réalisation de l'application1. La performance: Liée à la fois au langage hôte et à l'architecture même de la plateforme, celle-ci a un impact décisif sur la performance générale de l'application, puisque une grande partie des opérations de la plateforme applicative dépendronts des opérations de la plateforme agent. 1 Il est en effet difficilement pensable de ne pas réaliser la plateforme applicative dans le même langage que celui de la plateforme, principalement pour des raisons de performance et de simplicité. 34 Conception et réalisation d'une plateforme applicative pour le protocole SIP La section suivante présente l'ensemble des besoins qui vont nous permettre de proposer une solution adaptée. 3.2.2. Besoins La phase d'analyse préalable nous a permis de déterminer que les applications SIP avaient de fort besoin de communication, de réactivité et de concurrence. Pour répondre à ceux-ci, les agents doivent répondre aux caractéristiques suivantes: ­ Autonomie répond au besoin de concurrence. Un agent pourra continuer à gérer une communication tout en étant à l'écoute de messages provenant d'autres agents. Communication permet aux agents d'échanger de l'information. Cette caractéristique permet d'envisager une intégration profonde de SIP au sein de la plateforme agent. Contextualisation les agents opèrent dans un environnement, ici composé de serveurs distants, bases de données, autres entités SIP ou encore autre agents. La représentation de cet environnement facilite le partage d'information. ­ ­ Par conséquent, notre plateforme ne nécessite qu'un modèle d'agent simple, se limitant aux fondements des agents tels que nous les avons définis auparavant. Il est par conséquent peu adpaté de considérer dans notre cadre des modèles d'agents plus spécifiques, ayant par exemple des caractéristiques telles que la gestion d'une base de connaissance, un modèle d'intention, des croyances, etc. A l'inverse, certaines caractéristiques de ces agents, et notamment leur implantation dans la plateforme sont absolument cruciales: ­ Concurrence Les agents doivent pouvoir s'exécuter simultanément et faire également plusieurs choses en même temps. Certaines plateformes réalisent la concurrence des agents à l'aide de processus légers, d'autres utilisent des modèles spécifiques (coroutines, micro processus, etc). Le modèle d'execution choisi a un impact important sur la facilité de développement. Communication La plateforme doit offrir une infrastructure de communication suffisamment flexible pour y intégrer de nouveaux protocoles ou langages. Cet aspect est fondamental pour l'intégration de SIP au sein de la plateforme. Flexibilité La plateforme doit être suffisamment flexible pour permettre de spécifier le modèle agent proposé afin qu'il soit mieux adapté au domaine. En effet, certaines applications pourraient avoir à utiliser des modèles d'agents plus spécifiques que le modèle générique que nous avons présenté. Intégration avec l'existant Les agents doivent pouvoir s'intégrer aisément dans un ensemble de programmes déjà existant. Idéalement, les programmes existant pourraient être associés à des agents, de sorte qu'ils fassent partie intégrante du modèle du système. Performance ­ ­ ­ ­ 35 Conception et réalisation d'une plateforme applicative pour le protocole SIP Les communications, et notamment les communications impliquant des transport de données comme la voix ou la vidéo nécessitent une gestion assez fine du temps, et par conséquent de bonnes performances. Il est donc important que la plateforme ne représente pas une charge (mémoire et processeur) trop importante. On notera par ailleurs qu'il n'est pas important pour le moment que la plateforme soit distribuée, ou que les agents puissent migrer. En effet, les applications SIP communiqueront plutôt à l'aide du protocole SIP, ou d'autres protocole, que par un bus de messages/agents. 3.2.3. Problèmes Un des problèmes essentiel qui se pose lors de l'utilisation d'une plateforme agent est le modèle d'exécution qu'elle propose, c'est à dire de quelle manière la plateforme réalise techniquement la concurrence. La concurrence au sein d'une application est en général réalisée au moyen de processus légers, et rarement réalisée au moyen de processus lourds, ces derniers étant trop coûteux et difficiles à utiliser. A ce titre, on dénote deux grandes catégories de processus légers: Modèle de processus légers préemptifs: Un processus peut être interrompu à n'importe quel moment par le système (par l'ordonnanceur). Les processus n'ont pas ou peu de contrôle sur leur exécution. Modèle de processus légers coopératifs: Un processus ne peut être interrompu que lorsqu'il le permet. Les processus ne sont pas gérés par le système, mais plutôt par la plateforme. Il est donc plus facile de leur laisser le contrôle de leur execution. Nous allons détailler chacun des modèles, en mettant en avant leur caractéristiques. Modèle préemptif Le principe du modèle préemptif est de laisser au système d'exploitation l'exécution des processus légers. La politique d'ordonnancement du système prend de généralement en compte des niveaux de priorités qui permettent un contrôle mimium sur l'execution des processus. La caractéristique principale du modèle préemptif est qu'un processus peut être interrompu à n'importe quel moment par le système, et que par conséquent l'exécution des opérations n'est pas atomique. Par contre, la gestion des priorités et le fait que l'ordonnancement est géré par le système permet une répartition plus ou moins homogène du temps entre les différents processus (par exemple, on laisse 50ms à chaque processus pour s'exécuter avant de passer au suivant). Malgré cet avantage, il résulte du modèle préemptif des problèmes qui rendent le développement assez ardu: ­ ­ Les ressource partagées entre les différents processus (fichiers, données, etc) doivent être protégées contre les accès concurrents, car l'atomicité d'une opération n'est pas garantie. La synchronisation est complexe à mettre en oeuvre, en effet l'ordre d'exécution des processus n'est pas deterministe. 36 Conception et réalisation d'une plateforme applicative pour le protocole SIP S'ajoutent à ces problèmes de réalisation un ensemble de problèmes techniques sous-jacents: ­ ­ Les différentes implantations de processus légers système ont souvent des sémantiques légèrement différentes, ce qui rend la programmation dans ce modèle peu portable L'effort supplémentaire nécessaire à la protection des ressources et à la synchronisation a un coût en temps et en performance non négligeable. A ceci s'ajoute le coût des changement de contexte en mémoire, lors du passage d'un processus à un autre. Par conséquent, le modèle préemptif de base représente tout de même un ensemble de contraintes qui peuvent freiner ou limiter le développement d'applications réactives et concurrentes, de par la complexité de la mise en oeuvre. Pour résumer les caractéristiques du modèle préemptif sont les suivantes: ­ ­ ­ ­ ­ Exécution contrôlée par le système Gestion des priorités Fragmentation du temps relativement régulière Non-déterminisme dans l'exécution Pas d'exécution atomique d'opérations De manière générale, le modèle préemptif se prête bien au calcul scientifique, ou à des applications ne nécessitant que quelques dizaines de processus concurrents1. Au delà, et d'autant plus si il y a beaucoup de données partagées, le modèle préemptif peut poser des problèmes. Nous allons à présent aborder le détail du modèle coopératif. Modèle coopératif Le principe du modèle coopératif est de «remonter» la gestion des processus du système vers la plateforme. De fait, c'est la plateforme qui a le contrôle de l'exécution des processus. Le modèle coopératif va encore plus loin puisqu'il part du principe que ce sont les processus eux-même qui décident du moment où ils acceptent d'interrompre leur exécution au profit d'autre processus (par exemple en au moyen de l'operation yield(), en Java ou en Python). De fait, toutes les opérations effectuées dans le modèle coopératif sont atomiques: la plateforme ne pourra interrompre un processus entre deux yield(). Ceci nous permet également d'identifier les moments où le système est dans un état stable2. Par conséquent, il est inutile de protéger les ressources partagées par des accès concurrents, puisque nous avons la maîtrise de l'atomicité des opérations3. Il résulte pourtant de cet avantage un problème majeur: les processus déterminant eux-même les moments où ils peuvent être interrompus, nous avons une fragmentation du temps qui n'est pas homogène. En effet, certains processus pourront monopoliser l'exécution pendant 1s, alors que d'autres ne le feront que 5ms. La fragmentation du temps est donc relativement irrégulière et difficilement 1 Pour des raisons d'implantation du modèle préemptif et pour la difficulté croissante de la synchronisation Bien que le système ne soit pas forcément stabilisé à chaque appel de yield() 2 3 Ce qui peut tout de même être le cas dans le modèle prémptif, notamment lorsque le langage offre des primitives adéquate, comme le mot-clé synchronized en Java 37 Conception et réalisation d'une plateforme applicative pour le protocole SIP maîtrisable, la gesion des priorités est donc également difficile. Lorsque les changements de contexte deviennent trop importants (à cause de yield() trop fréquents), certaines réalisations du modèle coopératif subiront une forte baisse de performance, notamment par rapport au modèle préemptif. Par contre, un des avantages du modèle coopératif est que l'exécution est déterministe: les processus sont éxecutés systématiquement de la même manière, dans l'ordre de leur déclaration (ou selon des règles propres à la plateforme). Il en résulte qu'il n'est pas nécessaire d'effectuer autant de synchronisations (coûteuses et difficiles) que dans un modèle préemptif. Pour résumer, voici les caractéristiques du modèle coopératif: ­ ­ ­ ­ ­ Exécution contrôlée par la plateforme Fragmentation du temps irrégulière Gestion des priorités difficile Determinisme dans l'exécution Opérations exécutées de manière atomique Le modèle coopératif se prête plutôt bien aux applications communicantes et à celles partageant beaucoup de donnée, car il permet d'éviter les problèmes d'acces concurrents à des ressources et limite les problèmes de synchronisation. Toutefois, il est nécessaire de faire attention à la fragmentation du temps qui peut dans certains cas avoir un impact négatif sur les performances. Nous allons maintenant aborder les problèmes liés à la réalisation de la concurrence dans une plateforme agent, et notamment l'influence que celle-ci (dictée en partie par le modèle d'exécution) a sur réalisation d'agents. Réalisation de la concurrence La réalisation de la concurrence au sein des applications reprend de manière génerale le même principe que celui de programmes non-concurrents: le processus définit un point d'entrée (le main), qui est la fonction principale dictant le comportement du processus. Lorsque celle-ci se termine, le processus se termine également. Usuellement, ce point d'entrée est composé d'une boucle (de type while()), où le processus attend des évènements et décide de la prochaine action à effectuer en fonction des ces évènements, de l'environnement, et de son état. L'exemple ci-dessous illustre une manière de programmer un agent selon cette approche. class MonAgent { // Attribut des agents int etat = 0; Object attribut; ... // Operations 38 Conception et réalisation d'une plateforme applicative pour le protocole SIP void faitQuelqueChose() { // Traitement quelconque ... // On change d'état si une condition quelconque a été atteinte if ( ... ) { etat = 1; } } void faitAutreChose() { // Traitement quelconque ... // On change d'état etat = 2; } // Le point d'entrée dans le processus de l'agent void run() { while ( etat!=2 ) { if ( etat == 0 ) { faitQuelqueChose(); } else if ( etat == 1 ) { faitAutreChose(); } } } } Exemple 4 Un agent implanté sur un modèle de processus légers classique On remarque tout d'abord que l'intégralité du comportement de l'agent est orchestrée par la méthode run() faisant ici office de point d'entrée. Par conséquent, il faut avoir recours à des mécanismes supplémentaires pour permettre à l'agent de faire évoluer son comportement. En outre, la méthode run() est intrinsèquement séquentielle, ce qui tend à complexifier la réalisation effective du parallélisme impliqué dans la programmation concurrente. Un des autres travers de cette approche est qu'une concurrence interne à l'agent est difficile à mettre en oeuvre. En effet, l'utilisation d'un point d'entrée unique tend à associer un seul processus à un agent particulier, alors que dans bien des cas, un agent aura besoin d'effectuer plusieurs tâches en même temps. En revenant à notre besoin pratique, il est difficile avec cette approche, de penser qu'un agent va à la fois gérer une communication vidéo sur un canal de communication et en même temps réagir à des messages SIP. Ici, le comportement de l'agent est orienté dans une seule direction, figée dans la méthode 39 Conception et réalisation d'une plateforme applicative pour le protocole SIP run(), qui renforce encore l'aspect séquentiel, peu propice à la réalisation de la concurrence. Une réponse assez naturelle à ce problème est de faire que l'agent crée un nouveau processus pour chaque tâche, et que l'agent coordonne ces tâches entre elles. De fait, cette approche pousse les développeurs à modéliser de manière "centralisée", avec une entité qui contrôle les autres (un ordonnanceur ou «scheduler»), ce qui va à l'encontre de la caractéristique fondamentale d'autonomie des agents et limite une véritable coopération entre les agents. A cette approche, on préfera une approche plus réactive, où on l'agent va préférer réagir plutôt que de suivre une séquence d'actions (un plan) bien définies. L'exemple ci-dessous reprend le précédent avec une approche réactive: class MonAgent { // Attribut des agents Varidable etat = 0; Object attribut; ... // Operations void faitQuelqueChose() { // Traitement quelconque ... // On change d'état si une condition quelconque a été atteinte if ( ... ) { changeEtat(1); //Et on spécifie que que l'on veut quitter lorsque l'état passe à 2 whenEquals(etat, 2, new Thread(quitte)); } } void faitAutreChose() { // Traitement quelconque ... // On change d'état changeEtat(2); } // Le point d'entrée dans le processus de l'agent void activate() { //On utilise une primitive whenEquals qui execute la tâche donnee //en parametre lorsque l'etat est à 0 whenEquals(etat, 0, new Thread(faitQuelqueChose)); //Ici lorsque l'etat est a 1 whenEquals(etat, 1, new Thread(faitAutreChose)); } } 40 Conception et réalisation d'une plateforme applicative pour le protocole SIP Exemple 5 Un agent implanté sur un modèle réactif On remarque que cette approche est exprimée sur un mode plus déclaratif (ce que l'on veut faire), plutôt qu'impératif (ce que l'on fait) [19], et qu'il nécessite par conséquent des primitives dédiées à l'expression de la réactivité au sein de la plateforme (ici les opérations whenEquals). On notera ici que le point d'entrée activate() ne sert qu'à initialiser l'agent, et ne dicte en aucun cas la manière dont il va agir. L'avantage ici est que l'aspect séquentiel s'efface, laissant la place au concepteur pour penser librement la concurrence de son application. Ainsi, on pourrait très bien imaginer de faire deux chose en même temps lorsque l'agent est dans l'état 1: void activate() { whenEquals(etat, 0, new Thread(faitQuelqueChose)); whenEquals(etat, 1, new Thread(faitAutreChose)); //Ici on déclare que l'on fera deux choses simultanément lorsque //l'état sera à 1 whenEquals(etat, 1, new Thread(faitEncoreAutreChose)); whenEquals(etat, 2, new Thread(quitte)); } Il est également à noter que cette approche peut poser quelques problèmes dans un modèle préemptif. Tout d'abord, l'indéterminisme peut poser des problème de synchronisation, que pose également l'orchestration des changements d'état (la variable d'état doit être protégée contre les accès concurrents). 3.2.4. Proposition Nous venons de voir que les besoins relatifs au modèle d'agent sont relativement faibles: nous n'avons besoin que des caractéristiques fondamentales des agents qui sont l'autonomie, la communication et la contextualisation. Ensuite, nous avons vu l'importance du modèle d'exécution utilisé par la plateforme, ainsi que la manière dont la concurrence est réalisée dans celle-ci. Nous avons également présenté l'impact que peut avoir une plateforme au niveau de la conception d'applications. C'est donc en prenant en compte tous ces besoins, que nous allons détailler notre proposition. Réutiliser plutôt que créer La permière question à se poser est tout d'abord si il est plus intéressant de réutiliser ou de créer. Dans son article intitulé "Integrating Agents in Software Applications" [3], A.J.N. van Breemen présente justement la différence entre l'utilisation d'une plateforme existante et la création d'une nouvelle plateforme. 41 Conception et réalisation d'une plateforme applicative pour le protocole SIP D'après lui, le désavantage principal de l'utilisation d'une plateforme existante est qu'elle force le développeur à développer des applications avec un architecture «agent seulement" plutôt qu'une» architecture avec des agents". Dans son article, il décrit de manière très pragmatique les différents aspects qui permettent d'offrir les services qui vont permettre de soutenir une architecture orientée agent. Il est vrai que dans la plupart des cas les plateformes agent sont trop spécifiques, voire intrusives, pour s'intégrer correctement dans l'existant, tant au niveau des mécanismes d'exécution que dans la manière dont les agents communiquent. Cela dit, le choix de réutiliser une plateforme est en accord avec les principes que nous avons défini, et permettrait de gagner un temps précieux. Nous allons voir dans la section suivante comment et pourquoi nous proposons d'utiliser la plateforme agent Piranhas [23] plutôt que d'en créer une nouvelle. Celle-ci représente en effet une approche minimaliste et flexible permettant d'éviter les problèmes d'intégration. Piranhas: une plateforme légère et flexible La plateforme Piranhas est une plateforme agent écrite en Objective-C [18], placée sous une license libre, qui a été conçue pour offrir une infrastructure permettant d'appliquer la programmation orientée agent à un large cadre d'applications, en symbiose avec la programmation orientée objet. Piranhas résulte d'une approche pragmatique de la programmation orientée-agent, et vise à combler le fossé séparant (malheureusement encore) la théorie de la pratique. Les caractéristiques de cette plateforme sont les suivantes: Minimale: Piranhas n'offre pas de fonctionnalités superflues. Elle offre un modèle d'agent fondamental (autonomie, communication, contextualisation) et une architecture simple. Cette plateforme est donc légère, peu intrusive, et simple d'approche. Flexible: Piranhas ne prend aucun parti pris sur la nature des applications qu'elle va supporter. Par conséquent les modèle d'agent ainsi que les mécanismes de la plateformes sont adaptables en fonction des contextes. Extensible: Piranhas est architecturée selon le modèle de micro-noyau, offrant une segmentation très claire des différents services réalisant les caractéristiques des agents. Cette architecture également responsable de la flexibilité, permet très facilement d'étendre les fonctionnalités disponibles. Performante: Ecrite dans un langage compilé, relativement proche de la machine, Piranhas offre une performance rarement atteinte par les autres plateformes (en moyenne 10000 messages crées et échangés par seconde, et plusieurs dizaines de milliers d'agents supportés en parallèle). Transparente: Piranhas s'intègre sans difficulté avec des applications écrites en C ou en C++1. Par ailleurs, des techniques sont proposées pour intégrer de manière proche d'anciens composants logiciels dans le modèle d'exécution particulier à Piranhas. En fait, Piranhas offre les avantages offerts par l'utilisation d'une plateforme existante (services existant, architecture), mais tout en laissant le choix au développeur de l'adapter selon ses préférences au 1 Pour l'instant, seul le compilateur Objective-C d'Apple supporte l'extension Objective-C++, les patchs soumis aux responsables de GCC n'ayant toujours pas été intégrés dans la branche principale. 42 Conception et réalisation d'une plateforme applicative pour le protocole SIP programme. Ainsi il est tout à fait possible d'adapter Piranhas à une application dont l'architecture n'est pas «agent seulement», l'architecture de Piranhas permettant facilement d'y intégrer des éléments étrangers. En somme, les avantages offerts par Piranhas sont les suivants: ­ ­ ­ ­ ­ Piranhas est peu intrusive Ne force pas le modèle d'agent Ne force pas à faire que des agents Offre un modèle architectural flexible S'intègre avec du C et du C++ Piranhas dispose également d'un modèle d'exécution particulier, que nous allons détailler. Les avantages de son modèle d'éxecution Le modèle d'exécution de Piranhas est basé sur un modèle coopératif adapté pour pouvoir gérer un grand nombre de tâches simultanées et facilitant la création de celles-ci. Avant de détailler ce modèle d'exécution, il faut tout d'abord présenter les raisons qui ont motivé l'utilisation d'un modèle coopératif plutôt que préemptif dans Piranhas. Nous avons vu qu'un modèle coopératif simplifie la réalisation de la concurrence en évitant les problèmes d'accès concurrents (grâce au contrôle de l'atomicité des opérations) et évite les problèmes de synchronisation (grâce au déterminisme de l'exécution), mais ceci au détriment d'une fragmentation peu homogènene de l'exécution entre les tâches1. Les caractéristiques du modèle coopératif sont donc en adéquation avec la programmation orientée agent, fortement concurrente, mais également avec la programmation réactive. Frédéric Boussinot présente dans son article "Java Fair Threads" [5] un modèle d'exécution coopératif où la synchronisation des processus est facilitée par l'utilisation d'évènements. Un des principaux interêts de son article est de proposer que la notion de priorité est dénuée de sens dans un contexte équitable où les tâches ont toujours les mêmes droits à être executées, en fait l'ordonnanceur des Fair Threads définit un cycle d'exécution comme le fait que toutes les tâches aient atteint leur prochain point de coopération (l'equivalent de yield()). Frédéric développe également une comparaison des Fair Threads avec une approche liée à la programmation réactive. L'utilisation de processus légers, comme c'est le cas pour les Fair Threads implique des changements de contexte qui sont selon lui une des raisons de perte de performance dans l'utilisation de processus légers. Une approche réactive permet, en entrelacant des instructions atomiques appartenant à différents processus concurrents, d'éviter les changements de contexte, ce qui permet d'accéler l'exécution de ceux-ci. Piranhas dispose d'un modèle qui reprend le modèle d'exécution coopératif, mais en éliminant totalement le besoin de changement de contexte. L'approche choisie est la suivante: la plateforme dispose d'un service encapsulant un processus léger «système» (modèle préemptif). Ce service est nommé le service d'exécution'. Lorsqu'un agent (ou n'importe quel autre entité) veut effectuer quelque chose, 1 D'où, entre autres, de grandes difficultés de réalisation de temps réel 43 Conception et réalisation d'une plateforme applicative pour le protocole SIP il va encapsuler ce qu'il veut faire dans une action (auparavant appelée callback!) qu'il va soumettre au service d'exécution. L'action soumise par l'entité est mise dans une file d'attente qui est continuellement scrutée par le service d'exécution, qui va ensuite demander au processus léger qui lui est associé d'exécuter l'action scrutée. Ce mécanisme permet de garantir le determinisme (selon l'ordre de mise en file) et l'atomicité des actions soumises par les différentes entités, tout en éliminant les changements de contexte, car tout est opéré au sein du même processus léger, au sein du même espace d'adressage. D'une manière générale, on considère que l'entité demande à emprunter le flot d'exécution encapsulé par le service d'exécution. L'approche de Piranhas dérive également d'une problématique spécifique [22] à la manière de réaliser les agents: les agents reposent sur un ensemble de fonctionnalités (les services) fournies par la plateforme qui soutiennent leurs caractéristiques (autonomie, communication, etc). Le problème est de faire en sorte que le nombre d'agents évoluant dans la plateforme n'influe pas sur le temps alloué à l'exécution des services. Dans un modèle préemptif, il est difficile (en dehors de fonctionnalités temps réel) de spécifier des contraintes de priorité suffisamment fines pour permettre que par exemple, seulement 4 processus (les services) auront toujours 30% du temps d'exécution alloué à la plateforme. A ceci s'ajoute le besoin de concurrence interne des agents (le fait de pouvoir effectuer plusieurs tâches simultanément) qui engendre des inégalités dans l'allocation du temps processeur aux agents (ce sont les agents ayant le plus de tâches concurrentes qui auront le plus de temps processeur). La Le modèle d'exécution de Piranhas offre donc tous avantages suivants: ­ ­ ­ ­ Atomicité des opérations Determinisme (FIFO) des opérations Pas de changement de contexte Accès équitable au flot de contrôle Par contre, ce modèle ne permet pas de satisfaire des contraintes temps réel, de par la fragmentation non-homogènene engendrée par le modèle choisi. Néanmoins, il y a des solutions pour intégrer des entités temps-réel au sein de la plateforme, notamment en offrant un service dédié à l'exécution d'actions temps-réel, dont il faudra s'assurer qu'elles ne partagent pas directement des ressources avec les actions non temps-réel afin d'éviter les problèmes d'accès concurrents. Les avantages du langage Objective-C Le modèle d'exécution de Piranhas présente des avantages intéressants pour la réalisation d'agents, mais nécessite par contre que le langage d'implantation ait les caractéristiques adéquates. En effet, il est nécessaire qu'une fonction puisse être réifiée au sein du langage, c'est à dire que le langage soit capable d'exprimer, de représenter et manipuler l'objet correspondant à une action, donc à une fonction ou un appel de méthode (on parle alors de valeur de première classe) Les langages basés sur le lambda calcul (Lisp, ML) se prêtent particulièrement bien à l'implantation de ce genre de système, mais présentent le désavantage d'être peu ou mal connus, et de s'intégrer plus 44 Conception et réalisation d'une plateforme applicative pour le protocole SIP difficilement à l'existant (majoritairement du C et du C++). Le C permet également de représenter des pointeurs de fonction, mais n'offre par contre par de notion d'objet. Le C++, quand a lui ne permet pas de référencer une méthode d'instance: il faut que cetter dernière soit statique. Le langage Java ne permet pas (en dehors des mécanismes de réflexion, relativement lents) de référencer une méthode. En ce sens, le langage Objective-C [18] constitue un choix plutôt adapté au contexte des agents et en particulier au modèle d'exécution de Piranhas: Modèle objet: En Objective-C, les appels de méthodes sont considérés comme des échanges de message. Les objets ont un mécanisme d'héritance par classe. Résolution dynamique: Les objets communiquent entre eux en s'envoyant des messages caractérisés par leur sélécteur (l'équivalent du prototype d'une méthode, mais sans typage). La résolution de l'implantation liée au sélécteur est faite durant l'exécution du programme elle est donc dynamique1. Reflexivité: Le langage Objective-C est une extension très simple basée sur un moteur d'exécution lui-même écrit en C. Il est possible au travers de l'API de ce moteur de manipuler dynamiquement des objets et des classes Objective-C. Intégration avec C: Le langage C étant à la base d'Objective-C, et son moteur d'exécution étant écrit en C, il est très facile et naturel d'interfacer les deux langages, et donc de réutiliser des composants déja existants. Des extensions développées par Apple [1] permettent d'utiliser du code Objective-C et C++ au sein du même fichier. Portabilité: Objective-C fait partie intégrante du compilateur GCC, et dispose également d'une librairie complète et portable nommée GNUstep [9], également sous license libre. C'est en fait la définition même de l'objet dans le contexte d'Objective-C (une définition inspirée du langage SmallTalk) qui rend se langage adapté à Piranhas: en effet, la documentation du langage assimile les objets et les agents au même concept le modèle objet parlant d'échange de messages plutôt que d'appel de méthodes. L'utilisation des sélécteurs pour les échanges de messages permet effectivement de représenter et manipuler une entité représentant une méthode. Objective-C offre donc les caractérisitques suivantes: ­ ­ ­ ­ ­ Modèle objet avec héritage par classe Objets comme entités communicantes Résolution dynamique de méthode Intégration avec C Réflexivité On ajoutera également que notamment par rapport à Java, Objective-C est un langage performant. Comme simple illustration, Piranhas permet de créer et d'échanger près de 8000 messages par seconde sur un Pentium 200Mhz avec 32Mo de mémoire sous Linux, alors que la plupart des plateformes agent (généralement écrites en Java) n'arrivent qu'à quelques centains de messages par seconde dans les meilleurs cas, et sur des machines puissantes. Par ailleurs la plateforme Piranhas ne prend, lorsqu'elle est lancée avec l'intégralité de ces services, pas plus de 3Mo en mémoire. 1 Par ailleurs, son coût n'est que d'une fois et demi le coût d'un appel de fonction en C 45 Conception et réalisation d'une plateforme applicative pour le protocole SIP 3.2.5. Réalisation Nous proposons d'utiliser la plateforme Piranhas plutôt que d'en créer une nouvelle, étant donné qu'elle semble correspond à nos besoins, et qu'elle évite les désavantages tels qu'une implication architecturale trop forte, un modèle d'exécution peu adapté ou un manque de performance. Dans ce contexte, la seule réalisation concrète a effectuer est l'installation de Piranhas (et de la librairie GNUstep), et d'effectuer un ensemble de tests de performance. Il se trouve effectivement que Piranhas atteint plus de dix mille messages par seconde sur une configuration moyenne (type Pentium III 400Mhz), et que sa consommation en mémoire est à peine supérieure à 3Mo une fois lancée. 3.2.6. Synthèse Nous avons vu que réalisation de la concurrence et plateforme agent étaient très liés et que ceux-ci ont une influence sur la conception et la réalisation d'application. Nous avons proposé d'utiliser la plateforme Piranhas, pour les avantages de son modèle d'exécution, adapté à notre problématique, mais également grâce à sa discrétion et son intégration à l'existant. Le choix de cette plateforme conditionne en quelque sorte les étapes suivantes, étant donné que celles-ci vont devoir s'adapter aux contraintes et aux spécificités de Piranhas, comme nous l'avons présenté auparavant. 3.3. L'intégration du protocole SIP Maintenant que nous avons choisi d'utiliser la plateforme Piranhas, il faut considérer comment y intégrer le protocole SIP. Il s'agit tout d'abord de commencer par le choix entre utiliser ou créer une pile SIP, puis de l'encapsuler et finalement de l'intégrer au sein de la plateforme. La présente section détaille les besoins, problèmes, propositions et réalisations concernant l'intégration du protocole SIP au sein de Piranhas. 3.3.1. Introduction L'intégration du protocole SIP au sein de Piranhas repose principalement sur la pile SIP choisie, et plus particulièrement sur les aspects qu'elle supporte dans SIP. En effet, une pile SIP peut se décomposer de la manière suivante: ­ La couche transport Elle s'interface avec le système et les protocoles TCP et UDP pour permettre l'échange de messages SIP. SIP étant par conception abstrait de la couche transport, celle-ci peut être absente de la pile. Le traitement de messages Les messages SIP doivent pouvoir êtres lus (parsing) et convertis en une structure de donnnées accessible. C'est le plus bas niveau que l'on puisse trouver dans une pile SIP. La production de messages L'objet message doit pouvoir être converti à nouveau dans un format texte, sans quoi il est difficile de manipuler un message et de pouvoir renvoyer le message correspondant au résultat de cette manipulation. 46 ­ ­ Conception et réalisation d'une plateforme applicative pour le protocole SIP ­ La gestion de transactions SIP définit un modèle transactionnel représentant une séquence particulière d'échange de messages. La gestion des transactions permet d'associer un message entrant à une séquence de messages particulière. La gestion de dialogues Se placant au dessus du modèle transactionnel, le dialogue englobe en fait un ensemble de transactions entre deux entités SIP. Il définit un contexte commun à cet ensemble de transactions. ­ On pourrait encore ajouter à cette liste les facilités de négociation de session (notamment avec SDP), ou encore la gestion d'une communication complète. Ces aspects sont des services supplémentaires permettant de s'abstraire des opérations de bas niveau liées au protocole. En ce sens, ce sont les besoins que nous allons exprimer qui vont permettre de déterminer l'ensemble des caractéristiques requises par une pile SIP adaptée à notre plateforme. 3.3.2. Besoins Notre objectif de réaliser une plateforme SIP implique qu'il soit possible d'offrir au développeur à la fois des fonctionnalités de bas niveau (allant éventuellement jusqu'au choix du transport, SIP étant abstrait de celui-ci), que des fonctionnalités de haut niveau, comme la gestion de dialogues. Nous voulons également intégrer cette pile SIP au sein de Piranhas, bien qu'il n'y a pas de prérequis, cette intégration sera plus facile si la pile pile évite d'imposer un modèle d'exécution1. Dans ce contexte, on pourra définir les besoins suivants: Support de la RFC 3261: La pile SIP doit gérer la dernière version de la spécification du protocole SIP. Il existe en effet des différences importantes entre l'ancienne RFC (RFC 2543) et la nouvelle (RFC 3261) il serait peu adapté d'entamer le développement en ce basant sur une version dépréciée du protocole SIP. API pour les messages SIP: Le pile doit offrir une interface de programmation pour les messages SIP, de manière à les rendre manipulables en tant qu'objets. Ceci inclue également un analyseur de message et un moyen de produire le message SIP au format textuel à partir de sa représentation en mémoire (text objet texte). Stratification de l'API: Il est nécessaire d'avoir accès aux fonctions de bas-niveau de la pile, qui peuvent être nécessaires dans certaines applications. Par conséquent l'API doit être bien stratifiée, de manière à ne pas masquer les opérations de base liées au protocole SIP. Ceci implique qu'il doit être possible de contrôler et d'intervenir de manière assez fine sur le fonctionnement de la pile. Architecture extensible: SIP étant un protocole extensible, il est nécessaire que la pile elle-même permette de rajouter facilement le support de nouveaux éléments, notamment de nouvelles méthodes et de nouveaux champs dans les messages SIP. On rajoutera égalament un ensemble de besoins liés aux choix effectués précédemment: Realisée en C ou en Objective-C: De manière à minimiser la complexité de l'interfacage avec Piranhas, il est préférable que la pile soit écrite en C1. 1 De manière à s'intégrer de manière transparente dans le modèle de Piranhas 47 Conception et réalisation d'une plateforme applicative pour le protocole SIP Abstraite du modèle d'exécution: La pile ne devrait pas faire d'hypothèses sur le modèle d'exécution sous-jacent, notamment ne pas supposer que l'environnement est mono ou multi-tâches. Idéalement, la pile devrait supporter les deux modèles, et permettre d'enlever le support de l'un ou l'autre, ce qui dans le cas du multi-tâches permet d'accroître les perfomances. Libre, maintenue et documentée: Conformément aux volontés initiales, dans le cas où nous choisissons une pile SIP déjà existante, il est préférable que celle-ci soit disponible sous licence libre. Il est également nécessaire que dans ce cas la pile soit maintenue par son auteur, et qu'elle soit également documentée. Ce sont des critères de qualités minimaux pour un logiciel libre2. Ainsi nos exigences sont à la fois architecturales (contrôle et flexibilité), mais aussi techniques (implantation en C, licence libre). Nous allons maintenant détailler les problèmes qui peuvent survenir dans l'intégration de SIP au sein de Piranhas. 3.3.3. Problèmes Les problèmes majeurs qui peuvent se poser lors du choix d'une pile SIP et de son intégration dans Piranhas ont trait à la fois à la nature du projet (plateforme pour applications SIP) et à la nature de Piranhas. Tout d'abord, le fait de vouloir réaliser une plateforme pour applications SIP implique une exigence de flexibilité en ce qui concerne la pile SIP utilisée. Le problème étant, comme nous l'avons défini, que la qualité des applications SIP et leurs implications techniques sont pour l'instant difficiles à déterminer précisément. Par conséquent, nous ne sommes pas vraiment en mesure d'émettre des exigences précises concernant la flexibilité requise par la pile SIP. On pourra se contenter du fait de pouvoir intervenir dans la pile à tous les niveaux énoncés auparavant. Ensuite, l'intégration dans Piranhas se fera plus facilement si la pile ne comporte pas de partie autonome, ou n'implique pas l'utilisation d'un modèle d'exécution particulier. En effet, bien que Piranhas puisse très bien intégrer des éléments s'exécutant dans des processus lourds ou légers, il est bien évidemment préférable de pouvoir choisir différents modèles d'exécution. L'idéal serait de pouvoir choisir le modèle d'exécution qui convient à chaque strate de fonctionnalités de la pile, de manière à limiter au maximum les problèmes d'accès concurrents et de ressources partagées. Enfin, l'intégration d'une librairie en C dans Objective-C implique que la librairie en C ait une politique de gestion de la mémoire claire, qui lui permette de s'intégrer facilement dans le langage Objective-C qui offre un ramasse-miettes incrémental. En effet, une gestion de la mémoire confuse rendrait difficile la création d'une API Objective-C enrobant l'API offerte par la pile SIP. 3.3.4. Proposition En accord avec les besoins énoncés plus haut, et notre principe de réutiliser au maximum l'existant, nous proposons de réutiliser la pile SIP GNU oSIP, qui est un logiciel libre écrit en C. Nous avons 1 Comme nous l'avons mentionné, l'intégration d'Objetive-C et de C++ n'est pour l'instant possible qu'avec la version d'Apple, les modification ayant été soumises aux développeurs de GCC, mais n'ont toujours pas été intégrées. Dans certains cas, l'absence de documentation et/ou de support fait qu'il est plus simple de réecrire le logiciel plutôt que de le réutiliser. 2 48 Conception et réalisation d'une plateforme applicative pour le protocole SIP présenté cette pile lors de l'introduction. Cetter derniere est construite autour des caractéristiques suivantes: ­ Basée sur la RFC 3261 oSIP est construite de manière à suivre très fidèlement la proposition de la RFC 3261. Ceci garantit une bonne compatibilité avec les autres piles. Transactionnelle oSIP permet de gérer des transactions SIP, ce qui permet d'envisager un large panel d'applications SIP. La couche transactionnelle se base sur les automates représentant les transaction spécifiés dans la RFC 3261. Structurée L'architecture de oSIP est bien décomposée et structurée. Les API relatives à l'analyse, à la manipulation et à la production sont séparées des API relatives au transactions. Extensible Il est aisé de rajouter le support de nouvelles méthodes et de nouvelles en-têtes. Abstraite oSIP ne fait ni d'hypothèses sur le modèle d'exécution, ni sur la couche de transport. En fait, oSIP permet d'être compilé avec ou sans support du multi-tâches (préemptif), et laisse également à l'application le choix des mécanismes de transport de message SIP. Evènementielle oSIP est entièrement orientée-évènements. Ceci signifie que l'on enregistre des pointeurs de fonctions qui seront appelés lorsque certains évènements surviennent (arrivée d'un message, déclenchement d'un timeout). ­ ­ ­ ­ ­ Parmi ces caractéristiques, la gestion des transactions et l'approche évènementielle méritent d'être détaillés c'est d'ailleurs le propos de la section suivante. Modèle transactionnel et évènementiel Nous avons mentionné que la RFC 3261 définit la notion de transaction, et modélise celle-ci à l'aide d'automates a états finis. Ceux-ci définissent de manière plus formelle les étapes par lesquelles peut passer une transaction, ainsi que l'influence de divers évènements sur l'évolution d'une transaction. En fait, la RFC 3261 définit deux types de transactions: ­ Les transactions INVITE Initiées par une requête INVITE, elles ont la particuliarité d'inclure une procédure d'acquittement particulière (le three-way handshake, que nous n'aborderons pas ici). Les transaction non- INVITE Il s'agit de l'ensemble des transactions qui ne sont pas initiées pas une requête INVITE. ­ En prenant en compte le fait qu'une transaction implique qu'il y ait d'un côté un client et de l'autre un serveur, nous arrivons à deux automates par type de transaction, soit quatre automates en tout. La librairie oSIP n'intègre pas les automates au centre de sa conception, mais appose plutôt la partie consacrée aux messages SIP (ce que l'on peut considérer comme l'aspect stateless de SIP1) à la partie consacrée aux automates (la partie stateful). La figure 6 illustre les entrées, sorties et contrôles de 49 Conception et réalisation d'une plateforme applicative pour le protocole SIP chacun des composants. On remarque donc bien que partie FSM (Finite State Machine), consacrée aux automates. est séparée de la partie consacrée purement aux messages SIP. !"#$" %&'(")"($ *"++,-"./01 2!"#$%3 4,556,78+ 2&'()%*'(3 $ %&'(& !"# *"++,-"./01 2!"#$%3 %&'(")"($ %&'(")"($ Figure 6. API SIP et FSM dans oSIP En fait, oSIP considère une pile SIP comme l'apposition d'une API de création, manipulation, analyse et production de messages SIP et d'une librairie permettant de représenter les transactions, modélisées par des automates (FSM). Le lien entre ces deux composantes est à effectuer par l'application, et ceci est possible grâce au modèle évènementiel proposé par oSIP. La partie consacrée aux automates est en fait un composant prenant en entrée des évènements oSIP ou bien des messages SIP (sous forme d'objets, ou sous forme textuelle, dans quel cas l'analyseur de messages SIP est utilisé), et qui en contrepartie génère d'autre évènements et appelle des fonctions de rappel (callback) enregistrées de manière globale pour l'ensemble des transactions. C'est donc par l'enregistrement de callbacks et la soumission d'évènements que l'application contrôle l'exécution des automates, qui n'ont donc pas d'exécution propre. Ceci rend oSIP neutre vis à vis du modèle d'exécution de l'application qui l'utilise. Il est à noter qu'oSIP peut être compilé de manière à être protégé contre les accès concurrents. Un des avantages qu'offre l'architecture d'oSIP est de complètement décomposer les fonctionnalités: on a un couplage très lâche entre la partie liée aux messages SIP et la partie liée aux transactions. De même c'est à l'application de gérer le transport de messages SIP en enregistrant un callback appellé dès qu'un message doit être envoyé. Cette décomposition nous permet à la fois d'intégrer oSIP dans Piranhas avec le modèle d'exécution de notre choix, mais nous permet également d'avoir le choix du niveau d'abstraction avec lequel nous considérons les messages SIP. 1 Pour plus de détail sur les concepts de stateful et stateless, voire mon article sur SER et oSIP [34]. 50 Conception et réalisation d'une plateforme applicative pour le protocole SIP Le modèle évènementiel choisi par oSIP est également tout à fait cohérent avec l'approche de la programmation réactive, où la notion d'évènement est primordiale. Ainsi oSIP offre toutes les caractéristiques permettant une bonne intégration au sein de Piranhas. Définition de l'API Nous avons vu que la librairie oSIP offre la possibilité de créer et de manipuler des messages SIP (ainsi que leur conversion de et vers le format texte), mais également la gestion des transactions. Il existe de plus des extensions permettant d'ajouter la notion de dialogue et la notion de négociation de session (avec le support du protocole SDP). Il s'agit à présent de définir les caractéristiques que nous attendons de l'intégration de SIP au sein de Piranhas. Premièrement, il est clair que nous allons garder les niveaux d'API offerts par oSIP, c'est à dire le niveau message, et le niveau transactionnel. Nous considérons également que la gestion de dialogues ou de négociation de session se situe en dehors du cadre de la plateforme à cette étape de son développement. Ainsi, nous voulons pouvoir manipuler les entités suivantes: Message SIP: L'objet correspondant à un message SIP (requête ou réponse), constitué d'une première ligne décrivant le message, en-têtes et d'un corps. Transaction: L'objet correspond aux transactions. Il y a les transactions relatives à un message INVITE, et celles qui ne sont pas relatives à un message INVITE. Chacune de ces catégories est séparée en transaction client et transaction serveur. Il est à noter que l'application ne peut enregister qu'un seul rappel par type d'évènement, de manière globale. Ceci signifie qu'il n'est pas possible avec oSIP d'associer un rappel par type d'évènement par transaction, par conséquent oSIP ne permet pas (par défaut) d'associer un ensemble particulier de rappels à une transaction particulière. Il faut également noter qu'oSIP faisant abstraction de la couche transport, il faut que la plateforme définisse elle même la méthode de transport et la lie aux transactions. De même, oSIP n'offre pas de manière simple de construire des messages SIP aisément (par exemple une nouvelle requête ou une réponse à une requête). Il convient donc de munir la plateforme de facilités relatives à la création de messages. Pour résumer, l'API offerte par la plateforme doit comprendre, dans sa version primitive: ­ ­ ­ ­ La représentation des messages SIP et de leur contenu Un service permettant la création de messages SIP La représentation des transactions La gestion de la couche de transport 3.3.5. Réalisation Nous venons de détailler notre proposition d'utiliser la librairie oSIP pour intégrer le protocole SIP au sein de Piranhas. Nous allons maintenant voir le détail de cette intégration. Nous verrons tout 51 Conception et réalisation d'une plateforme applicative pour le protocole SIP d'abord comment l'interface de programmation pour les messages SIP a été réalisée, nous aborderons ensuite l'interface pour les transactions, l'intégration des automates dans le modèle d'exécution de Piranhas, la gestion de la couche transport, les facilités de construction de messages et pour finir le service SIP intégré au sein de Piranhas. Interface de messages SIP La première étape à effectuer dans l'intégration d'oSIP au sein de Piranhas est d'intégrer sa couche la plus basse: l'API de messages SIP. Pour ce faire, il faut tout d'abord résoudre une question principale: l'intégration des objets oSIP dans Objective-C, qui utilise un ramasse-miettes (incrémental). En effet, l'interfacage des objets définis par oSIP et écrits en C avec Piranhas implique de créer des classes Objective-C encapsulant les objets SIP. Or les instances de classes Objective-C sont soumises à la gestion de la mémoire par ramasse-miettes, il faut donc s'assurer que les objets oSIP ne sont pas désalloués alors que l'API Objective-C y accedra encore, et inversement. La première solution est d'effectuer autant que possible des copies des objets oSIP lorsqu'ils sont le résultat d'appels de fonction oSIP. Ainsi, il est garanti qu'oSIP ne libérera pas l'objet alors que nous en avons encore besoin. Lorsque l'on soumet un objet à oSIP, on pourra généralement compter sur le fait qu'oSIP ne désallouera pas lui-même l'objet en question, ce qui permet d'éviter de faire encore une copie. Cette solution, quelque peu coûteuse, permet néanmoins d'intégrer simplement les deux manières de gérer la mémoire. Cependant, il faut être vigilant quand au cycle de vie pointeurs donnés ou récupérés d'oSIP. Une seconde solution consiste à modifier les fonctions de désallocation d'oSIP pour que celles-ci prennent en compte la gestion de la mémoire d'Objective-C. Ainsi, par exemple, chaque objet oSIP pourra avoir un attribut booléen supplémentaire indiquant si l'objet est enregistré dans le ramasse-miettes ou pas. Si il ne l'est pas, il sera désalloué, sinon, la désallocation ne fera rien. Cette seconde solution rend les choses plus rapides et plus sûres, mais implique de modifier une partie du code source d'oSIP, et est donc à laisser pour plus tard. De manière à permettre une évolution de la première à la seconde solution sans impact sur le code, les objets oSIP sont encapsulés dans un objet de classe PSOsipObject1 ou dérivé. Cette classe permet de masquer les détails de la gestion de la mémoire, tout en donnant un dénominateur commun à tous les objets provenant d'oSIP. La figure 7 présente les classes principales qui composent l'interface de messages SIP, et qui encapsulent les structures définies par oSIP (représentées en gris sur la figure). On distingue les classes suvantes: : Définit une URI SIP. Ce sont elles qui permettent d'identifier une entité SIP, elles sont utilisée extensivement dans les messages. : Définit la classe abstraite correspondant aux en-têtes de message. Il y a beaucoup d'en-têtes différentes, celles-ci ne sont pas représentées sur la figure 7. : Définit le corps d'un message. Dans certains cas, un message peut avoir plusieurs corps. 1 Le préfixe PS signifiant Piranhas SIP 52 Conception et réalisation d'une plateforme applicative pour le protocole SIP : Définit un message SIP. On voit qu'un message SIP est composé d'un ensemble d'en-têtes et d'un (ou plusieurs) corps. Les deux spécialisations de cette classe (PSRequest et PSResponse) comportent des fonctions pour manipuler la première ligne du message, variant selon que le message est une requête ou une réponse. Figure 7. Diagramme de classe de l'interface de messages SIP Les classes PSUri, PSHeader, PSBody et PSMessage constituent donc la base de notre interface pour les messages SIP, et sont permettent notammant d'étendre SIP au moyen de nouveaux headers. Comme mentionné plus haut, oSIP définit un grand nombre de headers, en plus d'un ensemble d'accesseurs pour créer, supprimer, ajouter ou modifier chaque type de header. L'encapsulation ne tient pas en compte, pour l'instant, de tous ceux-ci. On notera tout de même que cette interface est entièrement indépendante de Piranhas, et qu'elle se borne en fait à encapsuler les structures C définies par SIP dans des classes. Nous ne détaillerons pas l'interface offerte par oSIP en elle même, mais de manière générale toutes les opérations sont en fait que des accesseurs pour les attributs. Interface de transactions L'interface pour les transactions est la seconde partie importante d'oSIP, et elle nécessite un travail plus poussé qu'une simple encapsulation de structures. En effet, l'intégration des transactions implique l'intégration des automates qui leur sont associés en plus de l'encapsulation des objets transaction dejà disponibles. L'intégration des automates requiert comme nous l'avons mentionné l'intégration du modèle d'évènements d'oSIP au sein de Piranhas. Commencons tout d'abord par aborder l'encapsulation des objets oSIP représentant les transactions. La figure 8 nous montre les structures oSIP (grisées) et les classes qui les encapsulent. On voit que les transactions définies par oSIP contiennent les informations suivantes: ­ Des en-têtes (From, To, Via, CSeq, Call-Id) correspondant aux en-têtes de la requête qui a inité la transaction. Ces informations sonc indispensables pour créer de nouveaux messages SIP 53 Conception et réalisation d'une plateforme applicative pour le protocole SIP Figure 8. Diagramme de classe de l'interface de transactions au sein de cette transaction. Elles sont par contre redondantes avec les informations contenues dans le dernier message reçu ou envoyé (selon le type de transaction). ­ ­ ­ ­ ­ La dernière réponse, la dernière requête, et le dernier acquittement envoyé ou recu, selon que la transaction est client ou serveur. L'état dans lequel se trouve l'automate associé à la transaction. Un contexte représentant les timers, la destination et le port courant (dans le cas d'une transaction cliente), paramétrant l'automate associé à la transaction. Les dates de création et de terminaison de la transaction. Les sockets d'entrée et de sortie. Ces champs sont en fait relativement inutiles, étant donné que c'est à l'application de prendre en compte le transport, et de plus redondant avec le point suivant. Le contexte de l'application. Le champ your_instance permet d'attacher n'importe quel objet à la transaction. On peut par exemple y rattacher des informations relatives à la couche de transport utilisée par le transaction, plutôt que d'utiliser les champs realtifs aux sockets. ­ Nous voyons donc que les informations sont relativement redondantes (requête originale et champs associés à cette requête), ce qui nous permet de simplifier l'API. Par ailleurs, oSIP ne distingue pas les transactions client ou serveur. Nous proposons donc les classes suivantes: ­ PSTransaction La classe générique, abstraite, qui définit les opérations communes aux transactions. On voit qu'il est possible d'accéder à la dernière réponse (envoyée ou recue) et la requête originelle (recue ou envoyée). On accède également aux dates de début et de fin de la transaction. L'operation terminate() permet de mettre fin prématurément à la transaction. ­ PSClientTransaction Définit une transaction cliente, qui permet d'accéder à la destination courante de la transaction (une adresse IP), et au port avec lequel se fait la communication. Ces données sont initialisées automatiquement par oSIP. On peut également envoyer un message par la transaction. On note que l'envoi de message ne nécessite pas que la transaction connaisse le mécanisme de transport 54 Conception et réalisation d'une plateforme applicative pour le protocole SIP associé: l'envoi d'un message par une transaction crée en fait un évènement qui est envoyé à l'automate associé. ­ PSServerTransaction Définit une transaction serveur. La seule opération possible est d'envoyer une réponse. Les classes encapsulant les structures d'oSIP liées aux transactions sont donc relativement simples. Par contre, nous n'avons pas encore fait le lien entre les transactions et les automates, ni entre les automates et l'application (il s'agit ici de Piranhas). La première des choses à remarquer est que les informations liées à la gestion des évènements SIP ne fait pas partie du «contexte» (de l'état) d'un automate: en effet, les structures osip_ict_t, osip_ist_t, etc, représentant les différents automates, ne contiennement pas d'attributs permettant d'exprimer qu'une transaction particulière aura des callbacks spécifiques pour certains évènements. Comme nous l'avons présenté, le modèle choisi par oSIP est que les callbacks enregistrés par l'application dans oSIP sont les mêmes pour toutes les transactions. Si l'on revient à nos considérations sur la programmation réactive, et que l'on considère que réagir à des évènements est un comportement, le modèle d'oSIP revient à dire que tous les agents utilisant SIP doivent avoir le même comportement. Ceci est bien évidemment peu intéressant par conséquent il faut mettre au point une architecture permettant d'enregistrer des callbacks spécifiques à une transaction particulière. Figure 9. Comportements dans Piranhas Pour ce faire, nous avons étendu Piranhas avec le notion de comportement, caractérisée de la manière suivante: un comportement est composé d'un ensemble de réactions à des évènements donnés. La figure 9 montre les entités suivantes: ­ PAction est une classe encapsulant une fonction (un callback). Certaines actions peuvent être paramétrées. ­ PReaction est une classe encapsulant une action paramétrable et associée à un unique comportement (cf. point suivant). ­ PBehaviour 55 Conception et réalisation d'une plateforme applicative pour le protocole SIP est une classe associant un ensemble de réactions à un ensemble d'évènements. Plusieurs réactions peuvent être attachées aux même évènement. Il est important de noter qu'il est possible de modifier les réactions associées à un comportement, que se soit en changeant l'action associée ou en ajoutant ou en supprimant une réaction pour un évènement donné. Pour revenir à notre problématique, le modèle de comportements offert par Piranhas nous permet d'associer aisément un ensemble d'actions aux évènements SIP (envoi et récéption de messages, timers, etc), et de les changer tout aussi aisément. Pour que les comportements représentent un véritable interêt par rapport aux rappels définis par oSIP, il faut permettre d'associer un comportement à chaque transaction. Figure 10. Integration des callbacks dans le contexte de transaction La figure 10 montre de quelle manière il est possible d'associer un comportement à chaque transaction. Il suffit en fait d'introduire une entité qui va être l'intermédiaire entre oSIP et les comportements de Piranhas. L'idée est d'exploiter la possibilité d'associer un contexte à chaque transaction oSIP: comme illustré par la figure 8, la structure osip_transaction définit un attribut your_instance, permettant de stocker n'importe quelle valeur. En associant une instance de comportement (PBehaviour) à une transaction (PSTransaction), elle-même associée à une transaction oSIP par l'attribut your_instance, il est possible d'obtenir dans une fonction de rappel enregistrée dans oSIP une référence sur la transaction oSIP, son encapsulation et surtout le comportement qui lui est associé. En effet, l'application enregistre dans oSIP des fonctions de rappel qui sont rappelées avec en paramètre la transaction concernée et éventuellement le message associé à l'évènement. Le principe est donc d'introduire un élément qui enregistre des fonctions de rappel dans oSIP dans lesquelles la réaction associée à l'évènement correspondant au type de rappel est executée. On voir sur la figure 10 que cet élément est une instance de la classe PSDispatcher. Ce dernier est effectivement l'entité qui engendre les réactions dans les comportements associées aux transactions lorsqu'un évènement se produit, en distribuant l'évènement au comportement concerné. Il reste tout de même un point important à aborder: l'intégration du répartiteur (dispatcher) dans le modèle d'exécution de Piranhas. En effet, comme nous l'avons vu, Piranhas est basé sur un modèle coopératif. Par conséquent toute exécution parallèle d'action présente un risque d'accès concurrents aux ressources, et donc de la violation de l'intégrité des données et du système. La solution est très simple: le répartiteur exécute les actions dans Piranhas même, bien qu'il soit appelé par oSIP. En pratique, une fois appelé par oSIP, le répartiteur va donner les actions associées à la transaction et à 56 Conception et réalisation d'une plateforme applicative pour le protocole SIP l'évènement (par les réactions aux comportements) au service d'exécution de Piranhas, qui exécutera l'action de manière asynchrone au sein du service d'exécution. Intégration de la couche transport dans le service SIP Nous avons montré qu'oSIP n'offre pas de mécanismes pour transporter les messages, ce qui est fidèle à la volonté d'abstraction de la couche de transport exprimée dans les RFC décrivant SIP. En ce sens, il est nécessaire d'intégrer au service SIP de Piranhas une gestion du transport. Pour ce faire, nous avons étendu Piranhas avec un service de transport (appelé «networking») suivant l'architecture illustrée par la figure 11. La notion de connexion, représentée par l'interface PConnectionProtocol permet de définir une source de données pouvant être lue, et dont l'arrivée de nouvelles données engendre une notification. On notera que le fait de pouvoir écrire sur une connection, et les modalités de cette écriture sont laissées à la discrétion des classes plus spécifiques (comme ici PUDPConnection, pour une adaptation de l'interface de connexion à un socket UDP). Figure 11. Service de transport par réseau pour Piranhas On voit également que le service de transport par réseau s'intègre dans le modèle d'exécution puisque lors de la notification de l'arrivée de données, l'exécutable (PParametrable1) est soumis au service d'exécution qui l'exécutera de manière asynchrone. Par contre, le service de transport par réseau utilise dans son implantation un processus léger appelant la primitive système select() pour détecter l'arrivée de nouvelles informations sur les connexion enregistrées. On pourra se reporter aux trames de conception Proacteur [25] et Réacteur [28] qui abordent les architectures synchrones et asynchrones de répartition d'évènements dans le cadre d'une approche réactive. Utilisation de constructeurs 57 Conception et réalisation d'une plateforme applicative pour le protocole SIP Nous avons vu comment les fonctionnalités offertes par oSIP ont été intégrées dans l'architecture de Piranhas. Il reste maintenant à aborder un point essentiel, qui est la création de messages SIP au sein d'une transaction. Il faut savoir tout d'abord qu'oSIP n'offre aucune fonction permettant de créer aisément des messages SIP valides, pire encore, oSIP refusera de fonctionner de manière brutale lorsque les messages ne sont pas conformes à ses attentes, c'est à dire lorsqu'ils ne sont pas conformes aux recommendations de la RFC 3261. Il faut savoir ensuite que la construction de messages est soumise à certaines règles, dépendant à la fois de l'agent utilisateur, de la version de la RFC utilisée par le protocole, et de l'échange précédent de messages. Par conséquent la construction de messages SIP gagne a être automatisée. L'idée que nous avons choisi est de se baser sur le patron de conception fabrication [20] (à ne pas confondre avec fabrique abstraite), de telle sorte que la manière de construire chaque message soit généralisée et paramétrable, car déléguée à une entité dédiée à la fabrication de messages. La figure 12 illustre la réalisation de ce patron de conception dans le cadre du service SIP. On voit que l'interface PSMessageFactoryProtocol définit la manière dont une classe de fabrication va être utlisé. Figure 12. Fabrique de messages SIP On note que le contexte d'une classe de fabrication est stockée dans une instance de PSMessageFactoryContext, qui contient en fait un ensemble de paramètres liés à l'agent utilisa- teur. Ceci permet de partager une même instance de fabrication entre différents UA ayant des contextes différents. De même, lorsqu'un message reçu nécessite la création d'une nouvelle transaction, il faut associer à cette transaction un comportement spécifique. Une fois encore, l'utilisation de la fabrication permet d'abstraire la manière dont le comportement est construit, et d'assigner le comportement à la transaction sans avoir besoin de connaître sa classe exacte. La réalisation est similaire à celle présentée sur la figure 12, on utilise cette fois une interface PSBehaviourFactoryProtocol réalisée par PSBehaviourFactory, qui permet de créer des coportements spécifiques à chaque type de transaction (ICT, IST, NICT et NIST). Aperçu du service SIP 58 Conception et réalisation d'une plateforme applicative pour le protocole SIP Nous venons de faire le tour des points impliqués dans la réalisation du service SIP. Il est temps maintenant d'observer de manière générale comment ce service s'intègre au sein de Piranhas. Figure 13. Diagramme de classe du service SIP pour Piranhas La figure 13 présente l'ensemble des classes abordées jusqu'ici et leur intégration avec le service SIP, implanté par la classe PSService. On voit que le service SIP offre les fonctionnalités suivantes: ­ ­ ­ Enregistrement d'une nouvelle connection, par laquelle peuvent arriver des messages SIP. L'invitation d'un agent. L'envoi d'une requête à un agent. On voit par la suite que ce sont les instances de PSConnection qui vont définir de quelle manière va être traité un message SIP arrivant: c'est elles qui associent (au moyen d'une instance de PSBehaviourFactory) un comportement (PSBehaviour) à la nouvelle transaction crée par l'arrivée du message (dans le cas où il faut créer une nouvelle transaction). A partir de ce moment, l'UA intéragira avec la communication SIP au moyen du comportement associé à la transaction qu'il contrôle (un UA peut bien-sûr contrôler plusieurs transactions) et de la transaction associée au comportement. De manière générale, on considèrera que: ­ ­ ­ Les connections et leur fabrication de comportements permet de déterminer le comportement à associer à un message arrivant, initiant une nouvelle transaction (transactions serveur) Le service SIP permet d'initier des transactions clientes, en spécifiant le comportement associé. Les transactions permettent au moyen de leur fabrication de messages, de créer facilement des réponses ou nouvelles requêtes, et de les envoyer à leur destinataire. La figure 14 présente de manière résumée la collaboration entre les différents objets participant à la réalisation du service SIP pour Piranhas. C'est la connexion qui initie le processus par la récéption d'un message initiant une nouvelle transaction serveur, y associe un nouveau comportement. Par la suite, 59 Conception et réalisation d'une plateforme applicative pour le protocole SIP Figure 14. Collaborations des entités du service SIP les nouveaux messages arrivant sur la connexion sont renvoyés par le service SIP qui est averti de ces nouveaux messages à oSIP. C'est ensuite le répartiteur (PSDispatcher) rappelé par oSIP qui se charge de notifier le comportement de l'évènement correspondant au callback ayant appelé le répartiteur. Le mécanisme est le même pour les transactions clientes, si ce n'est le fait que la connexion et le comportement voulus sont donnés par l'UA au service SIP, qui renverra à l'UA la transaction associée à la requête. L'UA pourra alors initier la transaction celle-ci n'est en effet activée qu'à la demande de l'UA. 3.3.6. Synthèse Nous avons comment oSIP répondait aux exigences de flexibilité et de décomposition requises pour une bonne intégration de la pile SIP au sein de Piranhas. Nous avons également vu comment intégrer une librairie en C dans de l'Objective-C, en prenant garde aux différentes manière de gérer la mémoire. Ensuite, nous avons présenté comment nous avons encapsulé oSIP de manière à offrir un niveau d'abstraction plus élevé, tout en garantissant l'accès aux éléments proches du protocole. Enfin, nous avons abordé la manière dont un UA intéragit avec les trois éléments essentiel de notre intégration de SIP à Piranhas que sont le service SIP, les connexions et les comportements. Par contre, on notera que nous n'avons pas présenté le système de communication par défaut of fert par Piranhas: en effet, nous avons intégré SIP comme un service de Piranhas, mais sans le faire profondément coopérer avec le système de message de Piranhas. Une intégration plus profonde nécessiterait l'emploi de nouveaux headers, et éventuellement l'ajout de nouvelles méthodes, ce qui constitue de fait un travail trop important pour trouver sa place dans ce projet. Ceci constitue par contre une évolution intéressante de l'intégration de SIP dans Piranhas. 3.4. Le langage de domaine Nous avons présenté dans les sections précédentes comment nous avons posé les bases de notre plateforme pour applications SIP. Nous avons choisi d'utiliser la plateforme agent Piranhas afin de faciliter la réalisation des aspects réactifs et concurrents des applications SIP, puis nous avons choisi la librairie oSIP pour intégrer le protocole SIP au sein de Piranhas. Nous avons montré en détail comment cette intégration s'est faite, ainsi que l'API en résultant. 60 Conception et réalisation d'une plateforme applicative pour le protocole SIP 3.4.1. Introduction Réaliser une application pour un domaine particulier nécessite une bonne compréhension de celui-ci, des ses problématiques courantes et des concepts clés qui lui sont associés. La première difficulté est donc une difficulté d'analyse et de modélisation, où il s'agit de ne pas oublier des aspects paraissant anodins, mais ayant un impact profond sur la résolution du problème. La seconde difficulté concerne la réalisation de l'application sur une plateforme particulière cette plateforme regroupant un langage, des librairies et éventuellement des modèles de programmation propres. Il se trouve qu'il existe un lien relativement fort entre l'aspect réalisation et l'aspect analyse: le choix de la plateforme a un impact non négligeable sur la manière d'appréhender une problématique. Ainsi, le choix du langage facilitera certains approches (si il est objet ou non, par exemple), ou orientera des pans entiers de l'architecture (langages fonctionnels, declaratifs, etc). En fait, le langage utilisé conditionne de manière assez forte les solutions qui seront proposées, dans le sens où il constitue un contexte qui expose les concepts qui seront manipulés et associés pour constituer une application, ou dans certains cas obscurcit, voir cache certains concepts qui devraient être mieux exposés. A ce titre, on peut également considérer qu'une interface de programmation conditionne les solutions et la conception d'une application. Ainsi par exemple la librairie du langage Java [15] pousse énormément les concepteurs à décomposer leurs applications et à utiliser des patrons de conception utliisés dans la librairie elle-même il y a donc une influence sur l'architecture de l'application. Le rôle des interfaces de programmation est en fait très similaire à celui des langages: exposer les concepts et entités qui vont servir à la construction d'applications, à ceci près qu'une interface ne peut pas améliorer l'expréssivité au delà du langage. Par conséquent, le choix de ces concepts est primordial: faire de l'objet en C est possible mais difficile, car le langage ne disposes pas de primitives réifiant les concepts objet. Il en résulte que peu de programmes C sont bien décomposés, flexibles et modulaires, et que peu de programmeurs C ont conscience de l'importance de ces aspects. Par contre, dans le cas d'applications Java, une large partie des applications sont concues et réalisées de manière à être flexibles et modulaires. Bien évidemment, ce n'est pas fondamentalement le langage qui empêche tel ou tel type d'application, mais c'est simplement le fait que le langage n'encourage pas (et parfois décourage) certaines approches qui pourraient être adaptées au domaine de la problématique. Il en résulte que le choix du langage de la plateforme est très important, car il conditionne la facilité de la réalisation, mais ce qui est encore plus important, la manière dont le concepteur va aborder une problématique. Nous allons donc proposer au cours de cette section un langage de domaine utilisable par les développeurs d'applications SIP, exposant tous les concepts et entités nécessaires à une conception et une réalisation appropriée d'applications SIP. 3.4.2. Besoins Comme nous l'avons introduit, à la fois le langage et l'interface de programmation représentent des aspects essentiels dans le développement d'applications. Objective-C est dans ce contexte un langage qui n'est pas complètement adapté aux problématiques liées au développement d'applications SIP, bien qu'il soit partiellement réflexif et dynamique, sa nature de langage compilé et la difficulté d'introduire de nouvelles primitives le rendent trop rigide pour en faire un langage de domaine, qui implique une bonne expressivité. 61 Conception et réalisation d'une plateforme applicative pour le protocole SIP Par conséquent, et comme c'est le cas dans de nombreuses applications, il est plus pratique d'embarquer un nouveau langage au sein d'Objective-C et de Piranhas, de sorte que les développeurs d'applications SIP puissent utiliser principalement ce langage pour créer des applications, et ensuite éventuellement utiliser du code C ou Objective-C pour des tâches nécéssitant plus de performance. Nous allons poser l'ensemble des besoins liés à un tel langage. Le premier besoin est celui de pouvoir prototyper rapidement des applications. En effet, plus le cycle écriture compilation test est court, plus les développeurs sont encouragés à expérimenter différentes approches, et donc plus le code aura de chance d'être bien adapté. Typiquement, les langages interprétés se prêtent bien au prototypage rapide par le fait qu'ils ne nécessitent pas de compilation et peuvent même souvent être interprétés lors de l'exécution de l'application. Un langage interprété permet donc par exemple d'ouvrir une console au sein de l'application et de créer à la volée des messages et des transaction SIP, d'y associer des comportements, de les modifier, etc. Il y a dans ce contexte un fort potentiel pour tout ce qui concerne l'écriture de tests ou le débugages d'applications. Il est par ailleurs utile que le langage soit réflexif , c'est à dire qu'il soit possible de manipuler les entités du langage lui-même. Un langage réflexif permet par exemple, si il est orienté objet, de prendre un objet, d'obtenir la liste de ses méthodes, et éventuellement de la modifier1: on pourrait changer le code associé à une méthode, en rajouter ou en supprimer. La réflexivité est aussi importante pour manipuler des objets dont on ne dispose pas d'information de type préalable (ce qui est le cas de la plupart des langages de scripts, qui sont faiblement typés). Le fait d'être interprété et réflexif sont deux traits garantissant une bonne flexibilité dz langages, mais ils ne définissent en rien les besoins relatifs au domaine ces traits sont avantageux de manière générale dans le cadre d'un langage embarqué au sein d'une plateforme. Nous pouvons aller un peu plus loin en considérant que le langage de domaine devra être le plus abstrait possible. Par abstrait, nous entendons qu'il offre une programmation la plus proche du domaine (qu'il soit de plus haut niveau), et la moins «engluée» dans des problèmes de performance ou d'implantation. Cette abstraction implique que le langage de domaine présente des primitives et opérations an totale adéquation avec le domaine, tout en gardant un cadre suffisament général pour pouvoir écrire des pans entiers de programme. C'est la détermination de ces primitives et opération qui s'avère être une des tâches les plus difficiles, comme nous allons le voir plus tard. De même, la réalisation des applications SIP à l'aide du langage de domaine implique il est nécessaire que celui-ci soit suffisamment évolué pour permettre une programmation avancée, offrant des structures de contrôles et un modèle de structuration/réutilisation du code, idéalement un modèle objet ceci aurait pour avantage de permettre un meilleur intégration avec Objective-C, ce dernier étant également orienté-objet. Enfin, on pourrait également vouloir que le langage de domaine ait des propriétés qui permettent de passer très facilement, sinon directement, de la modélisation et des spécifications à l'implantation. Ceci implique que le langage soit défini de manière formelle et exhibe des propriétés facilitant les vérifications. On notera à ce sujet que le trait de réflexivité est ici essentiel, puisque un outil de 1 En fait, la réflexivité s'arrête souvent à une API exposant les caractéristiques des types des objets disponibles dans le langage et dans l'applicaiton, sans pour autant pouvoir modifier cette information 62 Conception et réalisation d'une plateforme applicative pour le protocole SIP vérification de programme aura besoin de manipuler le programme lui-même, ce qui implique un haut niveau de réflexivité de la part du langage1. En fait, L'abstraction des concepts du domaine permet une expressivité plus grande, ce qui permet de diminuer autant que possible la différence entre les spécifications et l'implantation. Un langage de domaine a donc tout avantage à être le plus expressif possible, afin de se rapprocher des spécifications. Pour résumer, nous avons considéré les besoins suivants: ­ ­ ­ ­ ­ ­ embarquer le langage dans Objective-C et Piranhas prototyper rapidement des applications SIP éditer et manipuler interactivement des programmes introspecter une application en cours d'exécution offrir des abstractions du protocole SIP faciliter le passage des spécifications à l'implantation 3.4.3. Problèmes L'utilisation d'un langage de script au sein d'une application ne va pas sans poser de problèmes. Ces problèmes s'articulent autour des thèmes suivants: ­ ­ ­ Intégration au langage hôte Interaction avec la plateforme applicative Extension de la syntaxe du langage Le premier problème qui se pose lorsque l'on utiliser un langage embarqué est la manière dont celui-ci va s'intégrer au langage hôte. En effet, certains langages comme le C et le C++ n'ont pas ou peu de dynamisme, ce qui implique qu'ils s'interfaceront difficilement avec un langage très dynamique, comme le sont en général les langages embarqués (interprétés). A ceci s'ajoute également la différence entre le modèle proposé par le langage hôte et le modèle proposé par langage embarqué. Par exemple, cela peut poser des problèmes de faire intéropérer un langage embarqué orienté objet et du C. Dans le cas, souhaitable, où les deux langages ont un modèle objet similaire, il faut s'assurer qu'il est possible d'interfacer ces deux modèles correctement, ce qui aboutirait idéalement à la possibilité d'utiliser un objet déclaré dans un langage à partir de l'autre en fait, ceci équivaut à permettre d'utiliser de manière transparente un objet, quelque soit sa provenance. Malheureusement, ceci est très rarement possible, et la plupart du temps il y a un couplage lâche entre la plateforme applicative et le langage embarqué, du à la difficulté d'interfacer les modèles. Les interactions entre le langage embarqué et le langage hôte se font en général au travers d'une API plus ou moins contraignante. L'interaction entre le langage embarqué et la plateforme applicative est également une source de problèmes: dans le cas d'un couplage fort entre la plateforme et le langage, le problème principal est celui de la sécurité. En effet, si le couplage est trop fort, les applications écrites dans le langage de domaine ont un accès équivalent à la plateforme qu'un programme écrit dans le langage hôte il en 1 En fait, ce ne sont pas seulement les structures des objets qui sont exposées, mais également le code des opérations associées aux objets 63 Conception et réalisation d'une plateforme applicative pour le protocole SIP résulte des problèmes de sécurité et de possibles problèmes d'éxecution. En ce sens, il faut faire en sorte de pouvoir contrôler et filtrer les intéractions entre les applications écrites dans le langage de domaine et la plateforme applicative. Dans le cas d'un couplage lâche, le problème de sécurité se pose moins: un couplage lâche, et notamment quand les modèles des deux langages ne sont pas interfacés limite les risques d'accès à des ressources protégées. Par contre, il est alors nécessaire d'expliciter l'interface entre le langage de domaine et la plateforme applicative. Par exemple, dans le cas de l'intégration d'un langage à C++, ce dernier étant très statique et non réflexif, il serait nécessaire de spécifier l'ensemble des classes et opérations que le langage de domaines pourrait manipuler, ou bien de créer des adaptateurs (en C par exemple) entre les deux langages. Un des intérêts d'embarquer un langage est de pouvoir étendre sa syntaxe pour en faire un langage de domaine, dans le but de favoriser l'expressivité de ce dernier. Encore une fois, certaines difficultés peuvent survenir d'autant plus que la plupart langages ne permettent pas réelement d'étendre leur syntaxe (ou alors la tâche est difficile). Il faudra alors se contenter d'offrir une API cohérente et avantageuse (de plus haut-niveau) que celle de la plateforme, mais on perd alors un petit peu de l'intérêt d'avoir un langage de domaine. 3.4.4. Proposition Nous venons de présenter les besoins et les problèmes liés à l'intégration d'un langage au sein de notre plateforme. Comme auparavant, la première question à se poser est de savoir si nous allons créer un langage ou en réutiliser un. Il existe un nombre important de langage embarquables au sein d'applications écrites dans les langages de la famille C, et le nombre de ces petits langages semble croître relativement rapidement. Par ailleurs, comme nous l'avons dit, la création d'un langage depuis le départ est une tâche longue et relativement difficile, dont il serait bon de pouvoir se passer. Au regard des besoins exprimés précédemment, nous avons choisi d'utiliser le langage Io [13]. Io est un langage interprété, prototypé, dynamique et réflexif dont la conception favorise la simplicité et le minimalisme. Voici le détail de ses caractéristiques: Interprété: Io n'a pas besoin d'être compilé. L'interpréteur de Io peut être embarqué et "nourri" avec des programmes Io sous forme de fichiers ou de chaînes de caractères. Prototypé: Io dispose d'un modèle objet dépourvu de classes, où ce sont certains objets (les prototypes) qui vont servir de modèle à d'autres objets. Au lieu d'appeler le constructeur d'une classe pour obtenir une instance de celle-ci, on clonera plutôt un prototype. Dynamique: Les mécanismes du langages Io sont entièrement dynamiques. Par exemple, la modification d'un objet servant de prototype aura des repercussions sur tous ses clones. De même il est possible de modifier les opérations associées à un objet durant l'exécution du programme. Réflexif: Il est possible d'inspecter les objets, et de connaitre toutes les informations qui lui sont relatives (prototype, opérations, etc). Io va encore plus loin puisque même le code associé à l'objet est accessible et modifiable. Io est également qualifié de langage acteur, car il permet au moyen d'un opérateur (@) d'exécuter une opération de manière asynchrone. On dit alors que l'opération est exécutée par un acteur ce modèle est en fait très similaire au mécanisme des callbacks/actions présent dans Piranhas. 64 Conception et réalisation d'une plateforme applicative pour le protocole SIP La syntaxe de Io est relativement claire, se situant à mi chemin entre celle des langages Python (une opération par ligne) et Lisp (structure exprimée par des parenthèses). Elle est ne présente que très peu d'exceptions et se base sur le modèle syntaxique objet message(paramètres). En outre de ces traits, Io dispose de deux caractéristiques qui nous intéressent tout particulièrement: ­ ­ Il existe un «pont» permettant d'intégrer Objective-C et Io Il est trivial de rajouter de nouvelles primitives dans le langage Io est un logiciel libre (sous license BSD). Les traits qu'il exhibe et la présence d'un pont de et vers Objective-C rend Io un des langages les plus attrayants pour notre plateforme, d'autant plus qu'il est de haut niveau, très léger et également très souple. 3.4.5. Réalisation Nous avons donc choisi d'embarquer le langage Io au sein d'Objective-C et de Piranhas, puis d'étendre sa sémantique pour qu'elle soit offre des primitives et de constructs adaptés à la programmation d'applications SIP. Nous allons donc tout d'abord voir comment Io s'intègre avec Objective-C, puis comment nous l'avons intégré au sein de Piranhas. Nous allons ensuite détailler des primitives et constructs qui permettent de transformer Io en langage de domaine. Intégration avec Objective-C Comme nous l'avons déjà mentionné, le langage Io fournit par défaut un pont vers Objective-C. Ce pont est exceptionnellement petit et complet, en effet il permet une intégration complète et bidirectionnelle de Io dans Objective-C. L'idée fondatrice du pont est de fournir des adaptateurs pour le modèle objet d'Objective-C dans Io et vice versa. Ainsi, le pont se décompose dans les parties suivantes: ­ ­ ­ Un mécanisme de conversion des types Io vers Objective-C, et inversement Des adaptateurs Io Objective-C et Objective-C Io Une API pour la manipulation des classes Objective-C Il faut tout d'abord savoir qu'Objective-C n'est pas purement orienté-objet, alors que Io l'est. Pour Io, tout est un objet, alors que Objective-C hérite en plus des types de base du C (int, float, char, etc). Comme il est nécessaire de convertir les valeurs d'un monde à un autre, le pont doit offrir des mécanismes de conversion adaptés à chaque type. La conversion des types représente le premier niveau d'intégration entre deux langages. Il permet un échange de données de base, éventuellement par appel de méthodes néanmoins il ne permet pas une réelle communication entre les deux langages, notamment la manipulation d'objets venant de l'autre langage. La nature réflexive et dynamique de Io et d'Objective-C facilite grandement leur intégration: il est possible de reprogrammer la manière dont ces langages trouvent le code associé à un appel de méthode (un envoi de message) sur un objet. Dans Objective-C, une méthode est identifiée par un sélécteur, qui 65 Conception et réalisation d'une plateforme applicative pour le protocole SIP est un identifiant unique produit à partir du nom de la méthode (par exemple getTransaction). Dans Io, méthodes et attributs sont associés à des slots, accessibles par une chaîne de caractères. Il suffit alors de pouvoir convertir une chaîne en selécteur et inversement pour pouvoir rediriger un appel de méthode sur un objet d'un langage vers un objet de l'autre langage. Ainsi, l'utilisation d'adpatateurs encapsulant un objet Io ou Objective-C (respectivement dans Objective-C et Io) permet de manipuler un objet étranger comme si il était écrit dans le langage hôte. La manipulation d'objets étrangers est un aspect important, mais il est également appréciable de pouvoir mélanger les deux types d'objets: par exemple, il est intéressant de pouvoir faire hériter un objet Io d'un objet Objective-C, et vice-versa. Il est simple, étant donné la nature prototypée de Io de faire hériter un objet Io d'un objet Objective-C: il suffit simplement de l'assigner comme prototype de l'objet Io. Par contre, l'inverse est plus délicat car Objective-C est un langage compilé, utilisant des classes. Dans ce contexte, seul la possibilité d'étendre des objets Objective-C dans Io nous paraît intéressante malgré tout, il serait tout à fait possible d'implanter dans Objective-C un objet adaptateur qui utiliserait un modèle d'héritage par prototype, il suffirait alors d'assigner l'objet Io comme prototype de l'adaptateur. Techniquement parlant, le pont Io Objective-C n'éxistait que sous MacOS X, il a donc fallu le porter sur la plateforme GCC. Ce travail a été relativement simple, car la différence entre les API Objectve-C d'Apple et de GCC ne diffèrent presque que syntaxiquement. Intégration avec Piranhas L'effort principal à produire pour embarquer Io au sein de notre plateforme est de l'intégrer correctement dans Piranhas. En effet, comme nous l'avons montré, Piranhas a un modèle d'exécution particulier qui ne permet pas d'exécuter des actions en parallèle, car la plupart des ressources de Piranhas ne sont pas protégées contre les accès concurrents. Piranhas étant écrit en Objective-C, et Io étant parfaitement bien intégré à celui-ci, il est inutile de créer un pont spécifique Piranhas Io, le seul problème étant en effet l'intégration de Io dans le modèle d'exécution de Piranhas. Pour ce faire, il faut tout d'abord savoir que Io s'embarque sous la forme d'un interpréteur (une structure nommée IoState) représentant l'état global de l'interpréteur. Io étant un langage acteur il offre des primitives d'exécution asynchrones animées par des processus légers implantés au moyen de coroutines. Par conséquent l'emploi de l'opérateur d'exécution asynchrone créera un nouvel acteur qui sera executé de manière concurrente par rapport au reste de la plateforme. Cette concurrence pose problème, car elle met en danger l'intégrité de la plateforme. Il y a alors deux possibilités qui s'offrent à nous: 1. 2. Redéfinir l'opérateur d'exécution asynchrone pour qu'il soumette l'action à Piranhas, et évite donc une concurrence entre Io et Piranhas. Offrir une opération d'exécution asynchrone exécutant l'opération en tant qu'action Piranhas, et expliciter clairement le fait que l'utilisation de l'opértateur @ présente un danger. 66 Conception et réalisation d'une plateforme applicative pour le protocole SIP La première solution parait relativement simple, d'autant plus qu'il est trivial de redéfinir un opérateur en Io. Par contre, cette solution altère la sémantique du langage Io, et implique que des programmes écrits en Io que l'on voudrait utiliser dans une application pourraient ne pas fonctionner, ou fonctionner de manière incohérente. De plus, Io étant un langage en cours de construction, cette sémantique est susceptible de changer au fur et à mesure de son évolution. La seconde solution a l'avantage de ne pas impacter la sémantique de Io, mais par contre ne garantit pas qu'un programme ne sera pas exécuté en parallèle d'actions Piranhas. En fait, nous posons l'hypothèse que le développeur n'utilisera ces appels asynchrones qu'a bon escient, sachant qu'une mauvaise utilisation pourra mettre en danger l'intégrité de la plateforme. Ainsi, lorsqu'il voudra exécuter une action de manière asynchrone, sans compromettre la plateforme, il pourra utiliser des opérations dédiées. Ce sont justement ces opérations qu'il s'agit de définir. Pour ce faire, il faut reprendre les concepts du modèle d'exécution de Piranhas: ­ ­ ­ Une action (un callback) encapsule un bloc de code et ses paramètres. Le service d'exécution possède une tâche (processus léger) dont il prête le flot de contrôle aux actions pour qu'elles puissent s'exécuter. Les agents et programmes déposent les actions qu'ils veulent faire exécuter dans la file d'actions du service d'exécution Créer une action Soumettre l'action au service d'exécution. Par conséquent, les deux opérations que nous voulons pouvoir faire au sein de Io sont: ­ ­ Une action est un bloc de code pouvant prendre des paramètres. En ce sens, Io est très flexible, puisqu'il réifie la notion de bloc (qui n'est pas exactement similaire à la notion de cloture de la programmation fonctionnelle), au moyen des primitives block et method. Toutes deux permettent en gros de déclarer une séquence d'opérations et d'y rattacher un espace de résolution de variables augmenté de paramètres. #On definit un bloc de code comme on définit une valeur quelconque #on dit que les blocs sont des "types de premier ordre", car ils #sont référencables comme tout autre objet Io> print = block(text, Io> text print Io> ) Io> print("Hello!") "Hello!" #Ici on voit comment on peut assigner une méthode à un objet et #comment on peut la manipuler par la suite Io> o = Object clone Io> o print = method(text, text print) Io> print2 = o getSlot("print") Io> o print("Hello!") "Hello!" Io> print2("Hello!") "Hello!" 67 Conception et réalisation d'une plateforme applicative pour le protocole SIP Exemple 6 Réification des blocs de code en Io Cet aspect de Io est très pratique, mais l'idéal serait de pouvoir créer une fonction action qui prendrait en paramètre un bloc de code et qui retournerait une instance Objective-C de la classe PAction définissant une action Piranhas. Pour ce faire, Io nous allons utiliser le fait que Io considère du code comme des données, comme le montre l'exemple suivant. #On crée un prototype pour les actions de Piranhas Action = Object clone #Le prototype de ce prototype est une instance Objective-C Action proto = PAction alloc init #Il ne faut pas oublier de cloner le prototype dans notre cas Action clone = method( result = super clone result proto = PAction alloc init return result ) #On encapsule l'opération que va réaliser l'action Action setOperation = method(operation, self execute: = operation ) Action setOperation(method()) #Ceci est la nouvelle primitive qui va permettre d'executer de maniere #asynchrone un bloc de code action = block( action = Action clone #On récupère l'argument sans l'évaluer et on l'assigne action setOperation( message argAt(0) ) #On soumet l'action au service d'exécution au moyen du pont #vers Objective-C PExecutionService sharedInstance processExecutable:(action) return action ) #On peut désormer exécuter une action de manière asynchrone, en #garantissant qu'elle est exécutée au sein de Piranhas action("Hello!" print) Exemple 7 Passage de code comme données Comme on le voit sur cet exemple, l'ajout d'un prototype d'action (Action) et d'une primitive faisant office de constructeur (action()) permet de grandement faciliter la création d'actions et par conséquent de permettre facilement d'intégrer Io dans Piranhas: il suffit alors de passer n'importe quel bloc de code dans la primitive action pour qu'il soit exécuté en tant qu'action par le service d'exécution de Piranhas. 68 Conception et réalisation d'une plateforme applicative pour le protocole SIP Les autres aspects de l'intégration avec Piranhas, comme la possibilité d'écrire des agents directement en Io ne sont pas abordés ici, étant donné qu'ils ne présentent pas de difficulté grâce au pont Io Objective-C. Propositions de langages de domaine Le véritable enjeu lorsque l'on embarque un langage au sein d'une d'une plateforme est de bien définir les primitives qui vont offrir les abstractions les plus expressives pour le domaine. C'est donc avant tout un travail d'analyse, où il s'agit de mettre en avant les concepts fondamentaux liés au domaine. Il est important de savoir quelles sont les propositions existantes à ce sujet. En effet, notre langage de domaine doit être adapté à la programmation réactive et plus particulièrement à la description des comportements des agents, notamment vis-à-vis du protocole SIP. Nous allons présenter dans la section qui suit différentes approches qui apportent une perspective intéressante sur les langages de domaine. Les applications que nous voulons réaliser sont comme nous l'avons posé de nature réactive. Il existe un ensemble de langages, la plupart dérivés du langage ML, qui réalisent ce que l'on appelle la programmation réactive fonctionnelle1. A ce titre l'article de Zhanyon Wan et Paul Hudak intitulé "Functional Reactive Programming from First Principles" présente relativement bien les concepts fondamentaux de la programmation réactive fonctionnelle. Cet article a pour but d'explorer la sémantique formelle de la FRP et notamment de la manière dont on peut leamettre en relation avec une implantation basée sur la notion de flux représentant des comportements continus. Cette problématique est éloignée de la notre, mais l'article à l'avantage de bien présenter les concepts essentiels au travers d'une application de la FRP à la conception de contrôleurs d'interface graphiques. L'article se base sur une implantation de la FRP en Haskell, et aborde donc à la fois l'aspect pratique et théorique des concepts de la FRP, donc voici les deux concepts (et types) fondamentaux: Comportement: Un comportement est une valeur de type Behavior qui varie en fonction du temps (considéré dans le cadre de cet article comme continu). Un comportement peu être un nombre (auquel cas il est constant), une couleur, etc jusqu'au temps lui même. Evènement: Une valeur du type Event est une séquence d'occurences d'évènements ordonnée selon leur moment d'occurence (en fonction du temps, donc). Des évènements de base peuvent être par exemple un clic de souris, un appui sur une touche, etc. Il existe un ensemble de combinateurs qui permettent de composer de nouveaux comportements ou évènements à partir de ceux déjà existants. Un programme FRP est en fait une composition de comportements et d'évènements. A ces types de base s'ajoutent donc également les fonctions suivantes: 1 Nous en avons parlé dans la permière partie de ce document 69 Conception et réalisation d'une plateforme applicative pour le protocole SIP Jusqu'à: Permet de spécifier l'état «par défaut» d'un comportement, jusqu'à ce que l'évènement indiqué se produise. En fait, le until permet d'exprimer un état stable du comportement, ainsi que de rattacher des réactions (changement d'état) à un ensemble d'évènements. Exemple: Un comportement couleur rouge d'origine devient bleu quand survient un click de souris: color :: Behaviour color color = red 'until' (mouseClicked -=> blue) On peut même aller plus loin et proposer plusieurs réactions: color :: Behaviour color color = red 'until' (mouseClicked -=> blue .|. keyPressed -=> yellow ) Quand: Permet de transformer un comportement de type booléen (Boolean) en un évènement qui se produit exactement quand le booléen devient vrai (True), cet évènement est appelé évènement de prédicat. Exemple: Un comportement couleur rouge devient bleu quand le temps est plus grand que 5 (secondes): color :: Behaviour color color = red 'until' (when (time > 5) -=> blue) L'article présente également d'autres fonctions que nous n'aborderons pas ici, car elles sortent quelque peu du cadre qui nous intéresse car trop spécifiques. Néanmoins, les types et primitives que nous avons vu définissent en somme un cadre suffisamment souple pour la réalisation de programme réactifs. Les notions de comportement et d'évènement, bien qu'exprimées de manière plutôt formelle, nous montrent bien que c'est l'interrelation entre ces deux concepts qui donne le caractère dynamique des applications réactives. Ensuite, la manipulation des entités représentant ces deux concepts peut se faire à partir d'opérations permettant de relier une action (un changement d'état du comportement) à un évènement, ce que l'on pourrait considérer comme une réaction. Comme nous l'avons vu, il est utile de pouvoir combiner les réactions et de pouvoir exprimer des conditions (au moyen de prédicats) lors de l'association d'une action à un évènement. Il existe également quelques langages dédiés à la réalisation d'applications réactives qui ne sont pas basées sur la FRP. Parmi ceux-ci, le langage ProFun [26] se propose d'offrir un cadre adapté à la spécification et à l'implantation de prototypes de programmes réactifs. Pour ce faire, le langage ProFun propose une approche basée sur la décomposition d'une application en deux parties réalisées à l'aide de deux langages distincts: Le langage computationnel: Il définit la manipulation des données du système réactif. C'est un langage purement fonctionnel similaire à ML. Le langage de coordination: Il permet de spécifier la structure et le comportement dynamique du système. Ce langage est basé sur les algèbres de processus (création, communication, composition, etc) La séparation de la manipulation des données de l'approche comportementale est justifiée par les auteurs de ProFun par le fait que le propos de la programmation concurrente n'est pas simplement de paralléliser les programmes, mais également de permettre de décrire la distribution de ces programmes au moyen de concepts structurants. Il vient dont relativement naturellement que les problématiques 70 Conception et réalisation d'une plateforme applicative pour le protocole SIP liées au traitement des données (les programmes) sont presque orthogonales aux problématiques liée à la concurrence (les comportements). Dans cette perspective, les deux langages de ProFun peuvent être considérés comme deux couches: les transformations locales de données par les sous-systèmes, intégré dans une structure de sous-systèmes dont on décrit les intéractions. Dans ProFun, ces deux langages sont intégrés de maniègre asymétrique, c'est à dire que seul le langage computationel est intégré dans le langage de coordination, et non pas l'inverse ce qui est cohérent avec la vision de séparation des problématique, et le fait que les problèmes liés à la concurrence sont d'un niveau d'abstraction plus élevé que les problèmes liés à la manipulation des données. Un autre aspect intéressant soulevé par ProFun est le fait de pouvoir mélanger les styles déclaratifs et impératifs au sein du langage de coordination, ce qui apporte d'après les auteurs une plus grande liberté au programmeur. Il est interressant pour notre problème de détailler les opérations proposées par le langage comportemental. Rappelons tout d'abord que ce langage manipule des processus, et que ceux-ci communiquent au moyen de canaux bidirectionnels typés. Voici les opérations offertes par le langage comportemental: ­ ­ ­ Stop dénote un processus inactif Envoi et réception de données dénotés par les opérations de lecture et écriture sur des canaux typés (respectivement ! et ?) Evaluation dénote l'évaluation d'une fonction (d'un bloc de code), dont le resultat est affecté à un indentifiant. Terminaison dénoté par exit, il permet de terminer un procesuss. Contrôle dénotés par if, choose et test, ces trois opérations de style impératif permettent de changer le comportement d'un processus en fonction de conditions (expressions booléenes) ou évènement (activation d'un canal). ­ ­ Nous n'aborderons pas le langage computationel qui est proche de ML et ne présente pas un interêt fondamental par rapport à notre problématique. Par contre, nous pouvons noter tout d'abord que le langage comportemental est de style impératif , alors que le langage computationel est plutôt déclaratif (fonctionnel pur). Ensuite les opérations du langage comportemental n'offrent pas directement la notion d'évènement, qui sont en fait remplacés par la notion (plus restreinte) de communication par canaux (channnels): un processus n'intéragit avec son environnement que par ces canaux. Un canal est activé uniquement lorsqu'il y a un producteur et un consommateur. Ce modèle est en fait très proche des modèle de communication inter-processus utilisés dans le système Unix (les pipes), ils représentent effectivement une abstraction utile mais n'offrent pas directement le concepts d'évènement, qui paraissent plus généralistes et plus naturels, comme nous l'avons vu dans le contexte de la FRP. Malgré cela, Le langage ProFun présente l'intérêt de séparer explicitement les problématiques de traitement des données de l'aspect organisationnel/comportemental de ces traitements. L'utilisation d'un langage dérivé de ML encourage également les vérifications que l'ont peut effectuer sur le programme. 71 Conception et réalisation d'une plateforme applicative pour le protocole SIP Avec une approche similaire, mais dans un contexte différent, Munidar P. Singh propose dans son article "Toward Interaction Oriented-Programming" [35], dont nous avons déja parlé, une algèbre évènementielle compilable en contraintes de logique temporelle permettant de spécifier les intéractions entre des agents (nous nous situons donc dans le contexte de systèmes d'agents). L'algèbre proposée par Munidar P. Singh se base sur des opérations liées à des évènements. Un évènement peut être l'exécution d'un programme, l'arrivée d'une donnée, un timer, etc. Voici la liste de ces opérations, avec deux évènements U et V: ­ ­ U dépend de V La production de V implique la production de U, dans le cas ou U ne s'est pas déjà produit1 U empêche V La production de U empêche la production de V. Ceci signifie que V ne pourra se produire qu'avant U. U nourrit V V ne peut pas se produire tant que U ne s'est pas produit. Ceci permet de spécifier un ordre partiel entre les évènements. U nourrit éventuellement V Dans le cas où U se produit, il se produit alors avant V, mais V peut très bien se produire sans que U se soit produit. Garantir U permet V si il est certain que U va se produire, alors il est possible que V se produise. Dans le cas contraire, V ne pourra pas se produire. U initie V V ne peut se produire que si U s'est produit juste avant lui. Cette opération implique une notion de séquence atomique dans la production d'évènement, puisqu'elle interdit la production d'un évènement entre U et V. ­ ­ ­ ­ Ces opérations, bien que parfois complexes à comprendre permettent de mettre au point une algèbre (donc un cadre formel) permettant de spécifier et de démontrer des propriétés (étant donné qu'elle est compilable en contraintes de logique temportelles) sur des comportements. On remarque tout de même que cette algèbre implique une production atomique des évènements, et qu'elle serait plus complexe si elle devait prendre en compte des évènements se produisant en parallèle. Les opérations de cette algèbre sont également exprimées sur un mode déclaratif, où l'on spécifie plus les contraintes à respecter que la manière dont on applique les contraintes. On note également que cette algèbre manipule au travers des évènements un large ensemble d'entités, dont notamment des entités computationnelles (des programmes). Nous pouvons faire un parallèle avec ProFun, car ici encore cette algèbre sous-entend que ces évènements sont en fait des représentants de programmes réalisés dans un langage computationnel. Là où la proposition de Munidar P. Singh est intéressante est que cette algèbre utilise la notion fondamentale d'évènements (qui peu egalement permettre de construire la notion de canal utilisée dans ProFun), et fournit des opérations dont l'intérêt pratique est très accessible. Enfin, le style déclaratif 1 Le nom de cet opération est peu explicite, car on a tendance à penser que U ne peut pas se produire tant que V ne s'est pas produit, ce qui n'est en fait pas le case. 72 Conception et réalisation d'une plateforme applicative pour le protocole SIP de l'algèbre est très expressif et offre une abstraction de la réalisation des contraintes décrites par les expressions de cette algèbre. On trouve ici un lien assez fort entre les spécifications et la réalisation. Comme le dit lui-même l'auteur, l'algèbre qu'il propose offre les avantages d'offrir une sémantique formelle et une interprétation opérationnelle (relativement compréhensible), mais nécessite d'être enrichie d'abstractions exprimant la structure entre les programmes, entre leurs interactions. Ceci nous pousse à considérer que les problématiques liées à l'intéraction entre les processus et les problématiques liées à l'organisation des processus sont orthogonales, ou bien que ces dernières constituent une abstraction supplémentaire par rapport aux problématiques computationnelles et comportementales. Nous pourrions donc décomposer les problématiques dans l'ordre suivant: Computationel: La description des données et de leur traitement par un programme. Les langages à objet et les langages fonctionnels se prêtent bien à cette tâche. Comportemental: Que l'on pourrait également appeler interactionnel. Décrit les intéractions entre les différents programmes (et l'environnement, qui définit par exemple la notion de temps). Organisationnel: La description de la structure des différents programme et des différents comportements. Il s'agit là en fait d'une application des notions de spécialisation, de généralisation (héritage) et de composition aux programmes et comportements. Les aspects organisationnels restent encore pour l'instant une question en suspens (bien qu'il y ait différentes tentatives), et nous considérons qu'il est prématuré de s'y attacher pour l'instant. Il serait en effet trop long pour la durée de ce projet de tenter de mettre au point un modèle organisationnel, qui implique par ailleurs dans la plupart des cas la prise en compte de la distribution physique des processus sur différents processeurs et machines, et des stratégies de répartition de charge1. Le langage comportemental Nous venons de présenter différentes approches de langages de domaine visant la réalisation d'application réactives (et en interaction). Nous allons maintenant présenter notre approche en détaillant les primitives fondamentales (types et opérations) qui constituent les fondement de notre langage de domaine, que nous appellerons le langage comportemental. Tout d'abord, nous considérons la vision de la FRP et son identification des concepts de comportement et d'évènement, auxquels nous ajoutons la notion d'action: Action: Une action est une opération effectuée sur des données, l'envoi d'un message à un objet, la production d'un évènement, ou une combinaison de ces trois opérations de base. En fait une action est simplement un bloc de code encapsulé dans un objet. Evènement: Un évènement est la manifestation d'un changement. Celui-ci peut être l'évolution du temps, le changement d'état d'un objet, lié à la production d'un autre évènement, etc. 1 Et ne s'applique donc quasiement qu'aux agents ayant des caractéristiques leur permettant de migrer physiquement d'une plateforme à une autre 73 Conception et réalisation d'une plateforme applicative pour le protocole SIP Comportement: Un comportement est une description de la manière dont une entité va réagir à un ensemble d'évènements. On peut considérer les comportements comme le liens entre l'ensemble des actions et l'ensemble des c omportements. L'ajout de la notion d'action nous permet de nous abstraire totalement du langage computationnel en manipulant des objets représentant des traitements, les notions d'évènement et de comportement apportent les concepts fondamentaux permettant de représenter des changements, et la manière dont le système réagit à ces changements. Il s'agit ensuite de définir la manière dont ces trois primitives, ces trois objets intéragissent. Pour ce faire, il nous faut détailler deux aspects: Les évènements sont typés et structurés: Tout évènement survenant a un type (par exemple évènement réseau, utilisateur, système) et une origine (exprimée par une catégorisation comme application/sous-système/réseau). Ceci permet de considérer un ensemble d'évènements, en fonction et de leur type et de leur catégorisation. Les comportements sont dynamiques: Chaque comportement a la possibilité de changer au cours de son cycle l'ensemble de réactions par rapport à un type d'évènement. Ceci permet de faire évoluer le comportement en fonction, par exemple, de l'ordre dans lequel un ensemble d'évènements s'est produit, ou d'éviter qu'une réaction ne se produise plus d'un fois. La notion centrale est la notion de comportement, celui-ci crée un ensemble de réactions qui caractérise la mise en relation d'un type d'évènement donné, d'origine donnée à une action. La réaction, spécifique au comportement, matérialise donc l'association qui s'opère entre le type d'évènement, le comportement et l'action associée. Le comportement doit donc également encapsuler un état manipulable par les réactions, permettant de stocker de l'information utilisables par les réactions pour changer le comportement. Ainsi, les opérations offertes par un comportement sont: Associer une action à un type d'évènement: L'association d'une action à un type d'évènement crée une réaction spécifique au comportement. Cette dernière encapsule l'action et maintient des liens vers le type d'évènement auquel elle est associée, ainsi que le comportement auquel elle est rattachée. Encapsuler un état: Le comportement doit permettre aux réactions de communiquer de l'information entre elles. Pour ce faire, un état (ou contexte) associé au comportement permet à ces dernières de communiquer au travers de celui-ci. Encapsuler l'ensemble des réactions: Le comportement doit permettre d'accéder aisément à l'ensemble des réactions qui lui sont associées, et de manipuler cet ensemble. Ceci permet aux réactions de modifier le comportement. Il reste à savoir si notre modèle comportemental nous permet de réaliser les choses suivantes: 1. 2. 3. 4. Faire en sorte qu'une réaction ne se produise que si l'évènement respecte certaines conditions. Faire en sorte que la réaction ne se produise qu'un nombre déterminé de fois. Faire en sort qu'une réaction implique ou empêche la réalisation d'une autre Exprimer des dépendances entre les réactions. 74 Conception et réalisation d'une plateforme applicative pour le protocole SIP Pour qu'une réaction ne se produise que si l'évènement respecte des conditions, il suffit d'associer une expression faisant office de prédicat, gardant l'exécution de la réaction. Les réactions étant des objets, il s'agit dans ce cas d'une spécilisation du concept de réaction en réaction conditionnelle. Pour qu'une réaction en se produise qu'un nombre déterminé de fois, il faut que celle-ci maintienne un état permettant de déterminer le nombre de fois où elle a été exécutée, et de garder son exécution en fonction de la valeur de ce nombre. Il pourrait s'agir ici d'une spécialisaiton de la réaction conditionnelle. Pour qu'une réaction empèche l'exécution d'une autre, il faudrait soit garder l'exécution de la condition que l'on souhaite empêcher en fonction d'un état particulier du comportement, soit permettre à la réaction voulant empêcher l'exécution de l'autre réaction de la détacher (temporairement ou définitivement) du comportement. Ceci est possible grâce à la possibilité offerte par le comportement de manipuler l'ensemble des réactions. Enfin la dépendance entre les réactions implique qu'une réaction doit pouvoir ordonner l'exécution d'une réaction associée à un comportement, ce qui est encore une fois possible par la possibilité de manipuler l'ensemble des réactions associées à un comportement. Langage et API Le lecteur attentif aura fait un parallèle entre les extensions que nous avons rajoutées à Piranhas lors de l'intégration d'oSIP et le modèle comportemental. En effet, nous avons propsé un modèle comportemental pour Piranhas, implanté en Objective-C, définissant justement les notions de comportement, d'évènement, d'action et de réaction ce modèle a bien sûr été calqué sur les réflexions développées lors de la conception du langage de domaine effectuéee de manière parallèle (malgré la décomposition apparemment séquentielle de la réalisation du projet). Ainsi nous venons à une remarque intéressante: est-il nécessaire d'utiliser un langage de domaine si les concepts (le modèle) du domaine est exprimable dans le langage hôte, comme semble le montrer notre extension comportementale à Piranhas. En d'autres terme, cette remarque revient à se demander quelle est la différence pratique entre la création/utilisation d'une API et la création/utilisation d'un langage. En un sens, une API et un langage visent à la même chose: mettre à disposition des entités permettant de manipuler des concepts relatif à un domaine. La modélisation de ce domaine aura une grande influence sur la perception qu'auront les développeurs des problèmatiques qui lui sont associées, et orienteront les solutions qu'il pourra proposer. Là où API et langage diffèrent, est le fait qu'une API ne définit que de manière restreinte le mode d'expression et de manipulation de ces concepts. Une API ne fait que se greffer dans le moule imposé par le langage, alors que l'utilisation d'un langage spécifique permet au contraire de modeler le langage pour qu'il s'adapte le plus possible à l'API. En effet, les langages couramment utilisés permettent de réaliser beaucoup d'applications, de par leur nature généraliste. Pourtant, cette nature les rend parfois peu adaptés, voire contraignants à utiliser dans le contexte de certains problèmes. Nous avons vu par exemple que l'impossibilité de référencer un bloc de code rend difficile la réalisation d'applications réacives. A ce titre l'utilisation d'un langage de 75 Conception et réalisation d'une plateforme applicative pour le protocole SIP domaine, plus spécifique, permet de faciliter le développement en offrant un cadre adapté au domaine, plutôt qu'un domaine adapté au cadre. 3.4.6. Synthèse Nous avons exprimé au cours de cette section les besoins relatifs à l'utilisation d'un langage en tant qu'un langage de domaine. C'est à la lumière de ces explications que nous avons choisi le langage Io, pour ses caractéristiques de haut niveau et sa très bonne intégration avec Objective-C, le langage hôte de Piranhas, et mis au point un modèle comportemental caractérisant notre perception du domaine des applications réactives. Ce modèle comportemental se base sur l'expérience d'un ensemble de travaux relatifs à la programmation réactive, mais également sur la réflexion menée lors de l'intérgation de SIP au sein de Piranhas. Nous avons également montré les avantages dont dispose Io au niveau de son expressivité, notamment par la possibilité de créer des objets représentant des entités computationnelles (des blocs de code), essentielle à l'expression de comportements. Nous n'avons malheureusement pas la place dans ce document pour entrer dans le détail du langage de domaine, et de donner un ensemble d'exemples concrets de son utilisation. Néanmoins, nous avons abordé de manière théorique et également pratique la manière dont nous avons procédé pour la conception et l'intégration du langage comportemental à Piranhas. Il reste encore de nombreux aspects à développer. Tout d'abord, il serait très intéressant de définir formellement la sémantique du langage de domaine, et de se servir de la reflexivité de Io pour mettre au point une méthode de vérification de propriétés sur un programe comportemental. Ensuite, il serait intéressant de prolonger la modélisation du domaine avec une approche organisationnelle de la programmation réactive, car cette dernière n'a pas été prise en compte dans notre modélisation. Enfin, il serait intéressant d'analyser l'expressivité de l'API comportementale, et éventuellement d'enrichir Io de primitives permettant de se rapprocher encore plus des spécifications. 76 Conception et réalisation d'une plateforme applicative pour le protocole SIP 4. Synthèse Nous venons de voir au travers de ce document la réalisation d'une plateforme dédiée à la réalisation d'applications basées sur le protocole SIP, en se basant sur les domaines de la programmation réactive et concurrente, des systèmes d'agent, en embarquant et en spécialisant un langage de script au sein de cette plateforme. Nous avons présenté au travers de l'analyse préalable le protocole SIP, ses caractéristiques et applications. Nous avons ensuite pris du recul par rapport à celui-ci et avons proposé un ensemble de caractéristiques pour les applications utilisant ce protocole. Partant de là, nous avons effectué un bref aperçu des solutions logicielles existantes et également détaillé un ensemble de domaines que nous avons relié aux problématiques associées au protocole SIP. C'est dans ce contexte que nous avons relié la programmation réactive et la programmation concurrente aux agents et aux langages d'acteurs. Nous avons finalement abordé l'utilisation de langages de domaines dans le but d'améliorer l'expressivité des programmes, et de se rapprocher le plus possible des spécifications. C'est par une approche justement basée sur l'utilisation d'une plateforme agent dans laquelle nous intégrons le protocole SIP que nous avons proposé de réaliser la plateforme. Nous avons également montré que l'utilisation d'un langage de domaine permettait de faciliter le développement de programmes, au travers d'exemples concrets. Nous avons proposé partant de celà une décomposition de la plateforme en trois parties: la plateforme agent servant de base, l'intégration de SIP à celle-ci et enfin l'ajout d'un langage de domaine. La seconde partie de ce document, liée à la réalisation de la plateforme, nous à permis de définir les contraintes de réalisation et la méthodologie que nous avons choisi. Dans ce contexte, nous avons détaillé pour chaque partie les besoins, problèmes et réalisations qui leur sont rattachées. Nous avons ainsi vu les raisons pour lesquelles nous avons choisi d'utiliser la plateforme agent Piranhas, écrite en Objective-C, d'y intégrer la librairie oSIP, écrite en C, et enfin d'ajouter un langage comportemental basé sur le langage de script Io, écrit en C également. 4.1. Réalisation La réalisation de la plateforme a abouti à un prototype fonctionnel permettant de valider quelques cas simples d'application SIP. Il n'y avait pas spécifiquement de scénario à valider, ni d'application externe à intégrer, par conséquent l'intérêt pratique des exemples développés est faible, si ce n'est pour illustrer le style de développement engendré par la plateforme. La réalisation a été relativement simple au départ, notamment en ce qui concerne la plateforme Piranhas et la librairie oSIP. L'utilisation d'oSIP a tout de même nécessité un certain travail d'analyse du code source, étant donné que la documentation est quasi inexistant en dehors du document de référence qu'est la RFC 3261. C'est dans ce contexte que nous avons (avec l'auteur d'oSIP) effectué une restructuration de la librairie qui a résoluté dans l'évolution de oSIP version 1 vers oSIP version 2. Il reste néanmoins encore un important travail d'allègement à faire dans oSIP, qui contient malheureusement encore beaucoup de fonctions, attributs, et structures superflues, sans même aborder les possibles optimisations de performance. L'intégration d'oSIP dans Piranhas s'est faite sans trop de difficultés, à l'exception de l'évolution d'oSIP version 1 à oSIP version 2, et également de la gestion 77 Conception et réalisation d'une plateforme applicative pour le protocole SIP de la mémoire. en effet, oSIP n'est pas toujours très claire à cet égard, il faut donc faire attention. Le recours fréquent aux assertions et aux suites de test a permis d'éviter bon nombre de problèmes. De son côté, la spécification du langage de domaine et l'intégration de Io au sein de Piranhas a été bien plus difficile. En effet, il a été long et complexe d'abstraire les concepts liés au domaines, et malgré l'enchaînement logique présenté dans ce document, le déroulement concret s'est passé de manière bien moins séquentielle, où seules des avancées réciproques dans chaque partie du projet ont permis de progresser. Ceci a eu pour effet de considérablement rallonger le temps de développement: la conception étant très variable, notamment à cause des évolutions permanentes dans la modélisation du domaine, mais également à cause de l'apprentissage du langage Io et de son intégration dans Piranhas. En effet, le portage du pont Objective-C sous GNUstep a nécessité plusieurs semaines, étant donné l'absence de documentation (et parfois de commentaires) concernant l'implantation de Io et de la partie runtime d'Objective-C dans GCC. Cette première difficulté surmontée, il a fallu essayer différents moyens d'interfacer Io et le service d'éxecution de Piranhas, ceci ayant été compliqué par une évolution majeure du modèle objet de Io survenue courant avril, et à une latence dans les communications avec le concepteur de Io, ceci menanant parfois à une voir deux semaines d'attente d'une réponse cruciale. Globalement, c'est donc la réalisation du langage de domaine qui a coûté le plus d'efforts, mais a tout de même abouti à la spécification d'un modèle comportemental que nous avons appliqué à oSIP lors de son intégration dans Piranhas. Ce modèle en lui-même est encore assez jeune et mérite d'être éprouvé et de s'améliorer pour être plus en phase avec les besoins concrets de son application. Par ailleurs, l'intégration de Io dans Piranhas est extrêmement satisfaisante, puisqu'elle dépasse par exemple (en fonctionnalités et en simplicité) l'intégration du langage Python dans le langage Java (avec la librairie Jython), applaudi par la communauté des développeurs Java. 4.2. Organisation Au niveau de organisationel, le projet ne s'est pas déroulé exactement de la manière prévue (ce qui est effectivement une règle en informatique), ceci étant notamment dû à la difficulté de modélisation du domaine (nécessitant une bonne compréhension, et donc de l'expérience) et également à la difficulté d'intégrer Io à Piranhas. Les figures 15 et 16 montrent respectivement les plannings réels et prévisionnels. En pratique, l'intégration d'oSIP à Piranhas s'est faite plus rapidement que prévu, mais les difficultés rencontrées avec Io et la modélisation du domaine ont engendré un décalage du planning et à une réevaluation des jalons. En effet, il était prévu d'intégrer une infrastructure de filtrage de message (en fonction des valeurs de champs) au sein du service SIP, en utilisant l'extension comportementale de Piranhas. Néanmoins, le réevaluation permanente des objectifs en fonction des avancées, l'écriture de suites de tests, la validation, et la documentation de l'API a permis d'avancer de manière solide dans le développement de la plateforme. Il en résulte un code qui est de bonne qualité, au delà du prototype, bien qu'il ne soit pas encore complet. Au niveau organisationnel, l'application de la méthode extreme programming a permis d'assurer la maintenabilité du projet et la validité par rapport aux tests. Le maintien d'un blog quotidien et d'un site web a également permis d'informer l'environnement des avancées et décisions effectuées par le projet. Il est toutefois dommage que ce projet n'ait pas été appuyé de projets parallèles, comme notamment le 78 Conception et réalisation d'une plateforme applicative pour le protocole SIP 8 !+- 0 5$ 0 ) 6 , 7 &" &3 $ 7 !" # $ %& $ '( $) ? 3 2 , ( &$ 7 , ' F G ' . % $ &$ &9 # , # % $ H 9 ' * -. 9 '(% * # $ %+ ? 3 2 , ( &$ 7 , ' I G ' . % $ &$ &9 # , 3 7 &; A % " &3 $ 7 ' - $ ' , &' . 3 % " 7 < " ( , - %. , - %++& / ! " # # $ % &' ( ) % ' * + ! ' , &' $ * - . ! " # # $ % &' 1 , ' ( &" A , / , 0 &) % , ( ' 1 , ' 2 3 4 % , ( ' ( ) % ' * - . 8 7 " 29 ( , ' 1 , ' * + ! 8 7 " 29 ( , 8 7 " 29 ( , ' 1 , ' $ * - . 8 % 0 < 3 &, 0 &) % , ' . 3 % " 7 < " ( E $ * - . : $ 6 # % ; < , 7 ( 3$ 7 ' 1 , ' $ * - . 8 . - ' $ = > , &' # $ ) % ' $ * - . ? $ 1 ; 2 3 ( " &3 $ 7 ' 1 ) ' 1 $ 6 " 3 7 , ' @ 2 " 7 A " A , ' 1 , ' 1 $ 6 " 3 7 , B . % 3 6 3 &3 4 , ( ' , &' $ # ; % " &3 $ 7 ( ' 1 ) ' 2 " 7 A " A , ' 1 , ' 1 $ 6 " 3 7 , 8 % 0 < 3 &, 0 &) % , ' . 3 % " 7 < " ( E - $ 1 $ 2 3& / 4 5 6 1 * +7( / & + . % $ &$ &9 # , ( ' * + ! ' , &' $ * - . . % ; # " % " &3 $ 7 ' 1 , ' . 3 % " 7 < " ( + 7 0 " # ( ) 2 " &3 $ 7 ' 1 , ' $ * - . . % $ &$ &9 # , ( ' 3 7 &; A % " &3 $ 7 ' - $ - 6 # 2 " 7 &" &3 $ 7 - 7 &; A % " &3 $ 7 ' $ * - . ' 1 " 7 ( ' . 3 % " 7 < " ( * # ; 0 3 " 2 3 ( " &3 $ 7 ' 1 , ' - $ - 7 &; A % " &3 $ 7 ' - $ ' 1 " 7 ( ' . 3 % " 7 < " ( - 7 C % " ( &% ) 0 &) % , - 7 ( &" 2 2 " &3 $ 7 * 3 &, ' D , = + 7 4 3 % $ 7 7 , 6 , 7 &' 1 , ' 1 ; 4 , 2 $ # # , 6 , 7 & Figure 15. Planning réel 8 !+- 0 5$ 0 ) 6 , 7 &" &3 $ 7 !" # $ %& $ '( $) ? 3 2 , ( &$ 7 , ' F G ' . % $ &$ &9 # , # % $ H 9 ' * -. 9 * # $ %+ ? 3 2 , ( &$ 7 , ' K G ' . % $ &$ &9 # , 0 $ 6 # $ % &, 6 , 7 &" 2 : '(% ? 3 2 , ( &$ 7 , ' I G ' . % $ &$ &9 # , J 2 &% " A , ' 6 , ( ( " A , ( ' * - . , - %. , - %++& / ! " # # $ % &' ( ) % ' * + ! ' , &' $ * - . ! " # # $ % &' 1 , ' ( &" A , / , 0 &) % , ( ' 1 , ' 2 3 4 % , ( ' ( ) % ' * - . 8 7 " 29 ( , ' 1 , ' * + ! 8 7 " 29 ( , 8 7 " 29 ( , ' 1 , ' $ * - . 8 % 0 < 3 &, 0 &) % , ' . 3 % " 7 < " ( E $ * - . : $ 6 # % ; < , 7 ( 3$ 7 ' 1 , ' $ * - . 8 . - ' $ = > , &' # $ ) % ' $ * - . ? $ 1 ; 2 3 ( " &3 $ 7 ' 1 ) ' 1 $ 6 " 3 7 , ' @ 2 " 7 A " A , ' 1 , ' 1 $ 6 " 3 7 , B . % 3 6 3 &3 4 , ( ' , &' $ # ; % " &3 $ 7 ( ' 1 ) ' 2 " 7 A " A , ' 1 , ' 1 $ 6 " 3 7 , 8 % 0 < 3 &, 0 &) % , ' . 3 % " 7 < " ( E - $ 1 $ 2 3& / 4 5 6 1 * +7( / & + . % $ &$ &9 # , ( ' * + ! ' , &' $ * - . . % ; # " % " &3 $ 7 ' 1 , ' . 3 % " 7 < " ( . % $ &$ &9 # , ( ' 3 7 &; A % " &3 $ 7 ' - $ + 7 0 " # ( ) 2 " &3 $ 7 ' 1 , ' $ * - . - 6 # 2 " 7 &" &3 $ 7 - 7 &; A % " &3 $ 7 ' $ * - . ' 1 " 7 ( ' . 3 % " 7 < " ( * # ; 0 3 " 2 3 ( " &3 $ 7 ' 1 , ' - $ - 7 &; A % " &3 $ 7 ' - $ ' 1 " 7 ( ' . 3 % " 7 < " ( - 7 C % " ( &% ) 0 &) % , - 7 ( &" 2 2 " &3 $ 7 * 3 &, ' D , = + 7 4 3 % $ 7 7 , 6 , 7 &' 1 , ' 1 ; 4 , 2 $ # # , 6 , 7 & Figure 16. Planning prévisionnel développement d'une plateforme de tests pour le protocole SIP ou encore la réalisation d'application 79 Conception et réalisation d'une plateforme applicative pour le protocole SIP SIP avec une autre plateforme, ce qui aurait permis un échange d'idées autant qu'une aide concrète au développement. Le développement du projet aurait probablement été très avantagé par la présence d'une autre personne, notamment dans les moments où il y avait des difficultés à s'abstraire du domaine, ou à comprendre suffisamment l'implantation de Io pour l'intégrer dans Piranhas. Un point de vue différent et la possibilité de discuter avec des personnes plongées dans la problématique semble être un aspect fondamental du développement de logiciels. Par ailleurs, les concepts et technologies développées au sein de ce projet sont en rupture avec la culture actuelle de l'entreprise, et par conséquent ne pourront que difficilement être assimilées par la suite, un travail en coopération aurait assuré un transfert de connaissance pertinent. Le choix des langages (Objective-C et Io), de même que l'architecture (programmation réactive, agents) sont autant d'éléments nouveaux qui semblent perturber plus qu'ils ne suscitent l'intérêt. 4.3. Conclusion La conception et la réalisation de notre plateforme pour applications basées sur le protocole SIP nous a permis de montrer une alternative à la réalisation d'applications de communication utilisant le protocole SIP au travers d'une infrastructure généraliste. Néanmoins, il reste encore de nombreux points à défricher. Tout d'abord, il serait intéressant d'intégrer SIP bien plus profondément dans le système de communication de Piranhas, ceci impliquant sans doute l'ajout de nouvelles méthodes et de nouvelles en-têtes dédiées à la communication entre agents. La perspective d'utiliser SIP comme langage de communication inter-agents permettrait d'utiliser celui-ci au sein d'une architecture largement distribuée, mais également de faciliter la communications entre les entités. Ensuite, le langage de domaine pourrait être étendu de concert avec l'extension comportementale de Piranhas pour intégrer une approche organisationnelle des interactions, que nous avons séparée de l'approche purement comportementale. Enfin, et ceci est sans doute l'aspect le plus utile au protocole SIP, il serait bon de mettre au point, également en se basant sur l'extension comportementale, un mécanisme d'évènements et de filtres permettant de déclancher des réactions en fonction de conditions. Ceci permettrait de très facilement rattacher des comportements en fonction de certaines caractéristiques des messages SIP. Un des interêts de notre travail est d'avoir tissé des liens entre des domaines qui ont été peu rapprochés, et qui pourtant semblent répondre aux problèmatiques actuelles, où la communication, la réactivité et la concurrence deviennent des aspects essentiels. Il reste donc encore un large domaine à explorer, et surtout à faire mieux connaître les différentes alternatives à la fois technologiques et méthodologiques qui sont offertes aux développeurs et concepteurs d'applications. 80 Conception et réalisation d'une plateforme applicative pour le protocole SIP 81 Conception et réalisation d'une plateforme applicative pour le protocole SIP References [1] Apple Inc.. http://www.apple.com [2] A. [3] A. Tveit. van A survey of Agent-Oriented agents in Software software Engineering. applications. citeciteseer.nj.nec.com/tveit01survey.html Breemen. Integrating seer.nj.nec.com/vanbreemen02integrating.html [4] Erlang ­ Ericsson Language. http://www.erlang.org [5] F. Boussinot. Java Fair Threads, EMP-CMA/INRIA - MIMOSA Project, 10-06-2002. [6] M. Fisher. Representing and executing agent-based systems. In No title, pages 307­323. SpringerVerlag: Heidelberg, Germany. citeseer.nj.nec.com/fisher94representing.html [7] P. Hudak, A. Courtney, H. Nilsson, J. Peterson. Arrows, Robots, and Functional Reactive Programming, Yale University - Department of Computer Science. http://www.cs.uu.nl/~johanj/afp/afp4/ [8] GNU Is Not Unix ­ The Free Software Foundation. http://www.gnu.org [9] GNUstep ­ A free OpenStep implementation. http://www.gnustep.org [10] The Free Software Foundation. GPL ­ The GNU General Public License. http://www.gnu.org/licenses/gpl.html [11] The Haskell report, 2002. http://www.haskell.org [12] J. Hu and I. Pyarali and D. Schmidt. Measuring the Impact of Event Dispatching and Concurrency Models on Web Server Performance Over High-speed Networks, IEEE, November 1997. citeseer.nj.nec.com/hu97measuring.html [13] S. Dekorte. The Io programming language. http://www.iolanguage.com [14] JAIN SIP Specification, Sun. http://www.jcp.org/aboutJava/communityprocess/final/jsr032/index.html [15] Sun Microsystems. The Java programming language. http://java.sun.com [16] Lambda The Ultimate ­ A programmming languages weblog. http://lambda.weblogs.com [17] Migration [18] Apple. [19] J. and The Nordlander. Mobility: Semantics Objective-C Polymorphic Subtyping and Applications, INRIA. Language. citehttp://www-sop.inria.fr/mimosa/rp/ Programming in O'Haskell. http://developer.apple.com/techpubs/macosx/Cocoa/ObjectiveC/ seer.nj.nec.com/nordlander01polymorphic.html [20] E. Gamma, R.Helm, R.Johnson, J.Vlissides. Design Patterns: Elements of Reusable Object-Oriented design, 1995. [21] C.J. Petrie. Agent-Based Software Engineering. In No title. The Practical Application Company Ltd., Manchester, UK. citeseer.nj.nec.com/petrie00agentbased.html [22] Piranhas 2 ­ Concepts et réalisation. http://people.type-z.org/seb/pro/TW-Piranhas.pdf 82 Conception et réalisation d'une plateforme applicative pour le protocole SIP [23] Piranhas ­ Massive and aggressive agent systems platform. http://project.type-z.org/piranhas [24] W. Pree. Design Patterns for Object-Oriented Software Development, ACM Press and AddisonWesley, Reading, MA.. [25] I. Pyarali and T. Harrison and D. Schmidt and T. Jordan. Proactor - An Object Behavioral Pattern for Demultiplexing and Dispatching Handles for Asynchronous Events. citeseer.nj.nec.com/pyarali97proactor.html [26] Thomas Gehrke and Michaela Huhn. ProFun ­ a Language for Executable Specifications. citeseer.nj.nec.com/gehrke96profun.html [27] G. Doumenc, F. Boussinot. La Programmation par Objets Réactifs. cite- seer.nj.nec.com/219208.html [28] D.C. Schmidt. Reactor - An Object Behavioral Patterm for Demultiplexing and citeDispatching Handles for Synchronous Events, Washington University. seer.nj.nec.com/article/schmidt95reactor.html [29] M. Handley, H. Schulzrinne, E. Schooler, J. Rosenberg. RFC 2543 ­ SIP: Session Initiation Protocol, Internet Engineering Task Force, 1999. [30] R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee. RFC 2616 ­ Hypertext Transfer Protocol, Internet Engineering Task Force. [31] J. Rosenberg, H. Schulzrinne, G. Camarillo, A. Johnston, J. Peterson, R. Sparks, M. Handley, E. Schooler. RFC 3261 ­ SIP: Session Initiation Protocol, Internet Engineering Task Force. [32] C. Varela, G. Agha. Programming Dynamically Reconfigurable Open Systems with {SALSA}, pages 20­34. citeseer.nj.nec.com/varela01programming.html [33] J. Lennox, H. Schulzrinne, T.F. La Porta. Implementing Intelligent Network Services with the Session Initiation Protocol, 1999. http://www.cs.columbia.edu/~hgs/papers/cucs-002-99.pdf [34] S. Pierre. SER and oSIP: A short analysis of existing open-source SIP toolkits, Alcatel, 2003. [35] Munindar P. Singh. Toward Interaction-Oriented Programming. citeseer.nj.nec.com/singh96toward.html [36] J. Rosenberg, H. Schulzrinne. A Session Initiation Protocol (SIP) Event Package for Conference State, IETF, 2002. http://www.jdrosen.net/papers [37] H. Sinnreich, A.B. Johnston. Internet Communications Using SIP, Wiley & sons, 2001. [38] H. Schulzrinne. SIP implementations. http://www.cs.columbia.edu/~hgs/sip/implementations.html [39] F. Zambonelli. From Design To Intentions, Internet Engineering Task Force, 2001. citeseer.nj.nec.com/article/zambonelli01from.html 83