2009-02-09 6 views
3

Voici les spécifications:.NET Meilleure approche pour implémenter le modèle de mise en file d'attente client/serveur avec une application externe?

  1. clients en utilisant une application WinForms WPF sur leurs machines locales
  2. Les clients initient des requêtes au serveur pour exécuter une simulation. Cette initiation devrait probablement se faire via un service web mais d'autres suggestions sont les bienvenues
  3. Les requêtes sont mises en file d'attente sur le serveur
  4. Le serveur envoie des requêtes séquentielles au modèle de simulation via un service Web.
  5. serveur informe le client que la simulation est terminée

Une exigence supplémentaire est d'avoir un client annule une demande qu'ils ont déjà fait. Notez que nous n'avons pas à nous soucier d'envoyer trop de données dans le tuyau, nous envoyons seulement la confirmation qu'une exécution de simulation particulière est terminée (ou échouée)

Pour commencer, je pensais pouvoir faire tout cela avec un seul ASMX service web, mais maintenant je pense que cela pourrait être lourd. La WCF semble être une autre option, mais je ne la connais pas et cela semble beaucoup plus compliqué que la fonctionnalité dont j'ai besoin.

Des idées?

+0

Ne pas utiliser 1.) #text use 1. #text. SO fera un OL pour vous. –

Répondre

2

Client: Pour obtenir la notification d'achèvement, vous devrez utiliser le modèle de conception async lorsque vous appelez le service Web du client. Si vous utilisez "ajouter une référence Web" pour créer le proxy client, les méthodes de modèle asynchrone sont générées pour vous. Voir: "Access Web Services Asynchronously in .NET Design Patterns".

Serveur: vanille .Net 2.0 service web ASMX peut la file d'attente les appels entrants pour le traitement en série sur le serveur. Vous pouvez créer un répartiteur simple à l'aide de la classe BackgroundWorker. Le répartiteur prend chaque demande entrante et l'affecte à un thread d'arrière-plan. Pour sérialiser les threads, la méthode worker place un lock autour de l'appel de simulation. Voir this example d'utilisation des threads BackgroundWorker.

Annulation: Pour gérer l'annulation afin que le serveur retourne un identifiant unique avec sa réponse à la demande du client et insérez également l'identifiant et la référence workworker de fond associé dans un dictionnaire. Une méthode CancelSimulation sur le service Web accepte l'ID, recherche l'arrière-plan BackgroundWorker dans le dictionnaire et appelle sa méthode CancelAsync. Supprimez l'entrée du dictionnaire lorsque la tâche est terminée ou annulée. Le dictionnaire doit être partagé par tous les appels de service Web. Il doit donc être statique/partagé. Heureusement, un dictionary statique est thread-safe.

+0

C'est génial, mais qu'est-ce que je devrais construire le composant serveur? Un service Web asmx, un service Windows ou un service WCF? – Alex

+0

Le service Web .Net 2.0 asmx fonctionne correctement. Cela a un support intégré pour le modèle asynchrone. Il est vrai que la mise en file d'attente est intégrée dans WCF (je ne parle pas de msmq, mais seulement d'appels en série), mais BAackgroundWorker est plus simple. –

+0

Tom merci d'avoir développé votre réponse. Je vais essayer de mettre en place ce soir et sans aucun doute j'aurai quelques questions demain matin! Merci à tous pour votre réponse. – Alex

0

Vous devriez regarder de plus près à WCF. J'ai écrit une bibliothèque personnalisée pour le travail qui s'occupe de certaines configurations bizarres, mais vous pouvez écrire un excellent service web dans quelques dizaines de lignes de code avec WCF. C'est très extensible. Le seul problème est qu'il faut un certain temps pour "l'obtenir", mais une fois que vous faites c'est vraiment, vraiment simple. Bonne chance.

1

WCF semble être une autre option , mais je ne suis pas familier avec elle et il semble beaucoup plus compliqué que la fonctionnalité dont j'ai besoin.

J'incitons vivement que vous preniez un très bon oeil à WCF - oui, il pourrait être un peu plus intimidant au début, mais il vous donne beaucoup de flexibilité au moyen de configuration, plutôt que d'avoir à coder à un support de transport particulier (par exemple, service Web ou file d'attente de messages). Puisque vous dites explicitement que le client enverra des demandes à une file d'attente sur le serveur - pourquoi ne pas simplement utiliser un système de messagerie basé sur la file d'attente comme MSMQ en premier lieu? Avec WCF sur le serveur et le client, vous avez la possibilité de basculer rapidement entre l'utilisation de MSMQ et l'utilisation d'un appel HTTP SOAP "standard" par rapport à l'utilisation par exemple de la fonction WCF. un appel REST - tout dans la config. Ce type de flexibilité vaut la peine d'investir un peu de temps à apprendre, à mon humble avis.

+0

Je suis d'accord que WCF est une bonne approche pour cela - il peut même mettre en file d'attente des demandes entrantes en établissant un traitement de requête «un à la fois» (kludgy). Mais l'utilisation de la liaison msmq crée de la complexité pour la notification d'annulation et d'achèvement. –

+0

Oui - MSMQ a ses complexités - mais aussi ses récompenses! :-) C'est toujours une question de priorités et d'exigences. "Cela dépend" est la réponse ultime dans IT :-) –

1

Vous devriez regarder WCF. L'utilisation d'un service Web + sondage pourrait tuer votre serveur (à moins que vous n'ayez pas autant de clients) - regardez simplement Twitter. WCF a une connexion persistante qui devrait vous convenir parfaitement. En ce qui concerne la mise en file d'attente, ajoutez System.Messaging comme référence et utilisez MSMQ. Je ne me souviens pas s'il y a un transport MSMQ pour WCF, mais je suis sûr que vous pouvez en trouver un. L'utiliser ferait d'une pierre deux coups. Si vous voulez utiliser MSMQ, votre serveur devra être sur un domaine Windows. Dans le cas contraire, je vous recommande vivement d'écrire des événements dans une base de données et de les sélectionner à mesure que les threads de travail se terminent. Les conserver dans une file d'attente en mémoire n'est pas très tolérant aux pannes.

+0

Je suis d'accord que la file d'attente en mémoire des tâches de l'arrière-plan n'est pas du tout tolérante aux pannes, mais est-ce que la solution l'exige? Comme je l'ai noté dans le commentaire @marc_s MSMQ rend l'annulation et l'achèvement beaucoup plus compliqué que ne le fait un simple appel de service Web asynchrone. –

+0

Et un service Web asynchrone utiliserait des rappels, pas d'interrogation, pour la notification d'achèvement ou les mises à jour de programme. –

+0

@Tom, oui, vrai, un webservice asynchrone suffira: mais que diable: WCF l'a-t-il construit :). –