[C#] Envoyer un message à un service windows

Hello la zone,

Je suis en train d’écrire un service windows qui doit à un moment donné recevoir un message depuis une autre application (située sur une autre machine) via le réseau et lancer une action spécifique en fonction du type de message reçu.

L’idée étant de faire ça de manière extrêmement modulable et pouvoir très facilement rajouter un message et une action (voir carrément juste en modifiant le app.config pour rajouter un module externe).

Le truc c’est que je me tâte sur comment faire ce genre de chose. J’ai pensé à un simple listener UDP et des messages prédéfinis comme une chaîne de caractère permettant de faire le lien entre un nom et le module à charger, mais ça ne me satisfait pas vraiment… Surtout parce que je suis sûr qu’il doit exister une manière “classique” voir normalisée de faire ce genre de chose et que je préfère quand même utiliser une méthodologie compréhensible et testée plutôt que de réinventer la roue.

Ah dernière remarque, la sécurité n’est pas forcément la chose la plus importante, mais il est toujours préférable que ça ne transforme pas tout en passoire.

J’écoute vos suggestions, merci d’avance!

Gimly

Remoting avec TcpChannel ? (Ressemblant à un CORBA). Mais si tu n’as jamais gouté, tu risque de te casser un peu les dents. Un exemple de mise en place là : Remoting in C#.

Si tu peux bosser en .NET 3, tu as aussi WCF qui peut faire l’affaire : How to: Host a WCF Service in a Managed Windows Service.

La différence entre les deux est que Remoting est plus orienté “objets” : il permet réellement de simuler des classes qui se baladent au travers du réseau (tu manipules un proxy côté client dont les opérations sont effectuées sur une autre machine). Par contre son fonctionnement et ses subtilités sont assez complexes à saisir. Le top serait de trouver de bons exemples (le lien que je t’ai filé est une simple recherche google).

WCF est orienté messages, c’est la vNext des webservices classiques de asp.net 2.

Qq autres exemples de mise en place de remoting pour créer une petite application de chat : ici ou la.

Et c’est pas overkill par rapport à ce que je veux faire? Communication uni-directionnelle, peu de types de messages (1 seul pour commencer), etc.?

Quels sont les avantages par rapport à une approche type listener UDP tout con? (histoire d’avoir des arguments :))

Edit: ah et le passage au framework 3 n’est malheureusement pas possible, en tout cas dans l’immédiat

Y’a pas plus simple pour ce que tu veux faire. Je t’ai listé les trucs existants permettant d’implémenter ce genre de fonctionalité sans créer toi même ton socket. Si tu trouves ça trop lourd (le premier exemple filé fait quand même à peine qq lignes), alors point de salut : à toi les sockets en udp :slight_smile:

Les sockets sont tes amis. Si tu veux être sur que le message arrive, prend du TCP. Si tu veux pas te prendre la tête sur le parsing du message, utilise de la serialisation binaire. Faudrait que je retrouve, j’avais un bout de code qui faisait ça.

Hmmm… TCP / sérialization binaire, c’est juste éxactement comment fonctionne le remoting (quand tu le configure pour fonctionner avec du tcp/ binary). La différence, c’est que l’aspect envois / réception de messages est complètement prise en charge, quand tu appelles une méthode de ton objet distant.
De plus, tu peux configurer le bouzin pour authentifier l’utilisateur qui se connecte au service distant (c’est ultra-simple, surtout si tu es sur Active Directory), et depuis le Framework 2.0, tu peux demander à crypter les messages.

Moi perso je deteste le remoting pour ce genre de choses. Je trouve que c’est pas du tout adapte, le concept du MarshallByRef est pas adapte a la definition d’un contrat de communication de ce genre je trouve ou tu veux definir un contrat et ou le message n’a qu’artificiellement un lien avec objet. Client et serveurs deviennent intimement lies et inseparables et si c’est pas la meme chose vraiment fondamentalement au niveau du design c’est a eviter grave, tu veux une liaison pas en dur comme ca entre ton client et ton serveur, avec le contrat qui porte sur la communication, pas sur le binaire des deux cotes. Le remoting certes ca peut simplifier l’implementation mais a la limite je prefere un socket TCP avec un envois de int et de params pour les trucs a faire et basta :). Maintenatn si il s’agit de partager un object cross app domain… c’est pas pareil…

Enfin bon :crying: apres il fait comme il veut.

Donc si je comprends bien ce que dit GloP, utiliser le remoting n’est pas une bonne idée dans mon cas car ce que je souhaite faire est trop simple car le message que je vais transmettre n’est pas réellement un objet important mais plutôt une simple demande de faire une action.

Le remoting ce serait plutôt utilisé dans quels genre de cas alors?

Dans les mêmes cas où tu pourrais utiliser du Corba (à mon sens) : c’est à dire discussion interprocess (ou interdomaine dans le cas d’une appli Multi-AppDomain), séparation utilisation/implémentation.

J’utilise par exemple ça dans un framework qu’on a dévelopé permettant de gérer des plugins (l’AppDomain principal échange des objets avec les AppDomains contenant chaque plugin). Y’a toute une notion d’interfaces et d’implémentation dans chaque plugin pour ses traitements, etc. Mais dans ce cas le remoting n’est pas utilisé sur un TcpChannel mais directement en mémoire. (Le TcpChannel induit tout un système de serialisation & cie qui n’a que peu de sens quand tu te trouves sur la même machine).

Il existe aussi les IpcChannel pour faire du remoting entre process sur une même bécane (basé sur les canaux nommés). J’utilise ça pour faire de la communication interprocess (et pas de simples messages, là aussi ce sont des objets avec état et tout le toutim qui sont échangés).

Bref, pour une communication en messages purs (ce qui reviendrait à échanger des chaînes de caractère en remoting), effectivement, ça peut sembler inadapté. Après si tu peux vivre avec une dépendance forte entre ton client et ton serveur (la moindre modif sur la classe qui hérite de MarshalByRef oblige la recompilation des 2 projets), alors tu peux faire via Remoting.

Un truc qui est moyennement simple a implementer et qui te fournit l’opportunite de gerer une file d’attente et tout si t’as besoin c’est de faire du MSMQ en managed. T’as tout le multi-threading, ramassage de messages, processing, gestion quand ton service est pas en marche, transaction par message, etc, etc gratos. Et c’est pas si dur que ca a mettre en place en tant qu’element COM+ ou en tant que service windows. T’as un peu les memes contraintes vu que c’est un objet serialise que tu recuperes mais ca apporte plein de trucs (dont t’as ptet pas besoin donc a voir).

Ah bah j’allais dire qu’utiliser du Message Queuing pouvait peut être s’appliquer dans ce cas … :wink:
Beaucoup d’avantages effectivement en particulier pour la gestion du service / serveur offline.
MQ repond a beaucoup de problématiques que pose ton cahier des charges. Et te déchargera de pas mal de problèmes potentiels.

Au passage, WCF ca simplifie bien le truc pour MSMQ. Tu développe ca comme tu développerais une WebMethod, et tu l’exposes simplement via la couche de transport MSMQ. Ca se fait entièrement par configuration, et y’a pas mal d’exemples sur le WEB (Google-it, Live-searcg-it tout ca). C’est ce qui est utilisé dans le Back-end de BluePortal (le truc des gars de MS france pour créer son propre DailyMotion), pour servir d’éponge à “gros coup de mou” lors d’évènements importants avec pleins de gens qui upload leurs vidéos et qu’ils faut toutes les encoder en même temps avec juste un pauvre serveur qui en a ras-la-gueule.