Question

Je crée une interface utilisateur Silverlight 2 vers un instrument distant. Deux utilisateurs simultanés sur différents sites interagissent avec l'instrument (opérateur sur l'instrument et scientifique à distance) et un nombre illimité d'utilisateurs observateurs n'interagissant pas avec lui, juste en train de regarder. Cependant, chaque fois qu'un des deux utilisateurs actifs modifie quelque chose, ces modifications doivent être immédiatement reflétées dans les interfaces utilisateur de tous les utilisateurs, par exemple. effectuer un panoramique ou un zoom sur une image ou annoter ou sélectionner une partie d’une image, ajouter des éléments à une collection affichée dans une liste déroulante. Dans le client, j'utilise des collections observables qui reflètent facilement les modifications apportées par cet utilisateur, mais il est plus difficile de voir les modifications apportées par un autre utilisateur. Je peux rechercher les modifications de chaque client, mais il serait préférable d’utiliser des notifications push. J'ai abondamment cherché sur Google pour des exemples, mais je n'ai rien trouvé qui soit tout à fait ce dont j'ai besoin. Il existe toutes sortes de problèmes de sécurité liés à l'interaction de Silverlight avec les services WCF, ce qui signifie que de nombreux exemples potentiels ne fonctionnent tout simplement pas. J'ai essentiellement manqué de temps pour ce projet et j'ai besoin d'aide rapidement. Quelqu'un a-t-il des suggestions concernant un exemple simple, approprié, illustrant comment procéder? Je suis un développeur expérimenté, mais j’ai dû apprendre par moi-même les services Silverlight et WCF, et personne dans ma région n’en sait rien. Même si j'ai fait pas mal de travail sur ASP.NET, je ne suis pas un gourou du Web / Javascript. Merci.

Était-ce utile?

La solution

La notification push est prise en charge dans Silverlight 2 à l'aide du nouveau support WCF PollingDuplexHttpBinding. Deux ensembles sont installés avec le SDK Silverlight ( une pour l'application Silverlight, une pour le serveur WCF ).

J'ai un quelques blogs. publications et un exemple complet d’application qui montrent comment «pousser» les mises à jour de Stock depuis un serveur d’applications console hébergeant un service WCF sur des clients connectés. Il montre également comment chaque client peut ajouter des notes à un stock et les synchroniser (transférées du serveur) vers tous les autres clients connectés.

La dernière version de l'exemple (partie 4) montre comment synchroniser les mises à jour envoyées entre les clients Silverlight et WPF à l'aide de deux points finaux de serveur, comme suit:

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace StockServer
{
    public class StockServiceHost : ServiceHost
    {
        public StockServiceHost(object singletonInstance, params Uri[] baseAddresses)
            : base(singletonInstance, baseAddresses)
        {
        }

        public StockServiceHost(Type serviceType, params Uri[] baseAddresses)
            : base(serviceType, baseAddresses)
        {
        }

        protected override void InitializeRuntime()
        {
            this.AddServiceEndpoint(
                typeof(IPolicyProvider),
                new WebHttpBinding(),
                new Uri("http://localhost:10201/")).Behaviors.Add(new WebHttpBehavior());

            this.AddServiceEndpoint(
                typeof(IStockService),
                new PollingDuplexHttpBinding(),
                new Uri("http://localhost:10201/SilverlightStockService"));

            this.AddServiceEndpoint(
                typeof(IStockService),
                new WSDualHttpBinding(WSDualHttpSecurityMode.None),
                new Uri("http://localhost:10201/WpfStockService"));

            base.InitializeRuntime();
        }
    }
}

Les clients WPF se connectent au point de terminaison WSDualHttpBinding et les clients Silverlight se connectent au point de terminaison PollingDuplexHttpBinding du même service WCF. L'application indique également comment gérer les exigences de la stratégie d'accès du client Silverlight.

Les clients (Silverlight ou WPF) peuvent ajouter des notes à un stock dans leur interface utilisateur et ces notes sont renvoyées au serveur pour être repoussées vers tous les autres clients. Ceci démontre la communication dans les deux sens et réalise, espérons-le, toute la communication nécessaire à votre application.

Vous pouvez voir une capture d'écran de application de démonstration exécutée ici .

Autres conseils

Ce n’est pas pour autant que nous poussons Flex à la mode des fans, mais c’est en fait le type d’architecture que nous intégrons régulièrement dans toutes nos applications basées sur Flex. Voici ce que nous faisons sur Flex - il ne fait aucun doute que cela pourrait être traduit correctement dans Silverlight:

Nous prenons trois ingrédients et les intégrons ensemble pour réaliser cette capacité:

  1. Modèle de comète (moyen compatible HTTP de faire des notifications push sur le serveur - consultez Wikipedia pour plus d’informations)
  2. sujets de messagerie JMS (files d'attente de publication / abonné)
  3. Le servlet Adobe BlazeDS

Ce dernier élément implémente le modèle Comet, prend en charge le marshaling d'objets AMF (format de sérialisation binaire d'Adobe pour les objets ActionScript3) et établit des ponts avec une file d'attente ou un sujet JMS. Lors du pontage vers un sujet, plusieurs clients Flex exécutés dans un navigateur peuvent être mandatés en tant qu'abonnés à un sujet JMS. Ainsi, si un client publie un message (ou si le code côté serveur est publié dans le sujet), le message sera transmis à tous les abonnés du client via BlazeDS et l’implémentation de Comet Pattern.

Effectivement, vous devez localiser ou écrire un composant qui remplit les fonctions de BlazeDS. Vous devrez peut-être également implémenter un code client qui interagit avec le modèle Comet de ce composant côté serveur.

La WCF prend-elle en charge le modèle de la comète et la messagerie bidirectionnelle? Particulièrement lorsque conforme à HTTP et au port 80 ou au port 443 pour SSL. On dirait que vous avez déjà étudié la question et que vous n'avez rien trouvé pour la messagerie bidirectionnelle. Vous devrez peut-être vous retrousser les manches et coder.

Remarques à propos de la transmission poussée du serveur vers une application Web:

BlazeDS prend en charge deux modes principaux d’implémentation du motif Comet (il existe en fait une troisième option d’interrogation mais je l’ignore):

  1. interrogation longue
  2. diffusion HTTP

Le type d'interrogation longue que vous devriez trouver plus compatible avec la plupart des navigateurs Web. Vous pouvez donc rationaliser simplement pour supporter cela initialement. Vous pouvez également passer votre temps à faire en sorte que votre code client teste d'abord le streaming HTTP et, si nécessaire, opte pour une interrogation longue.

En ce qui concerne un courtier de messages pouvant fournir une capacité de publication / abonnement, vous pouvez envisager d’utiliser ActiveMQ JMS. Il est open source et gratuit avec un soutien actif de la communauté (vous pouvez également acheter de l’aide). De plus, vous pouvez utiliser NMS pour une intégration en tant que client .NET.

Avoir un courtier de messages assis dans le niveau intermédiaire est en fait important car ce sera un endroit où les messages seront placés en toute sécurité. Si vos clients effectuent une interrogation longue, vous ne voudriez pas qu'ils ratent un nouveau message pendant un intervalle pendant lequel ils ne sont pas connectés.

Un autre élément à prendre en compte dans les scénarios de volume de trafic élevé (des centaines ou des milliers de clients, tels qu'un site Web sur Internet), consiste à adopter une approche évolutive du modèle de la comète.

Dans le monde Flex / Java, le servlet BlazeDS (open source) a été modifié pour fonctionner avec un modèle asynchrone. En Java, un écouteur de socket peut être construit pour utiliser les canaux NIO et les pools de threads Java Concurrency Executor. Le serveur Web Tomcat dispose d'un écouteur NIO et d'une prise en charge des événements asynchrones Servlet 3.0. BlazeDS en particulier a été modifié pour fonctionner avec le serveur Web Jetty. L’essentiel est que l’évolutivité de cette approche asynchrone signifie qu’un seul serveur Web physique peut être amélioré pour prendre en charge jusqu’à environ 20 000 connexions client simultanées de type Comet.

Cela fait longtemps que je n’utilise pas la programmation .NET, mais les fonctionnalités d’IO ressemblaient beaucoup à Java 1.1, à l’exception du gestionnaire de résultats asynchrone. Toutefois, cela n’a rien à voir avec la création d’écouteurs de sockets asynchrones via des canaux Java NIO. Une implémentation de canal NIO peut prendre en charge des centaines, voire des milliers, de connexions de socket avec un pool de threads relativement petit. Mais C # et .NET sont passés par

Je voulais juste préciser que PollingDuplexHttpBinding n'implémentait pas de "vraies" notifications push, car il révèle son nom (polling). De la documentation msdn :

  

Lorsqu'il est configuré avec cette liaison, le client Silverlight interroge périodiquement le service sur la couche réseau et recherche les nouveaux messages que le service souhaite envoyer sur le canal de rappel. Le service met en file d'attente tous les messages envoyés sur le canal de rappel du client et les remet au client lorsque celui-ci interroge le service.

Cependant, il est plus efficace que la méthode classique d’interrogation d’un service Web, car après chaque interrogation, le serveur garde le canal ouvert pendant un certain temps (par exemple 1 minute) et, si un message arrive à ce moment-là, directement 'pousser' le message au client. Le client doit renouveler sa connexion à plusieurs reprises, pour ainsi dire interroger le service.

Si vous souhaitez implémenter de véritables notifications push avec silverlight, j’estime que vous devez travailler avec des sockets et je vous recommande de lire quelques-uns des blogs de Dan Wahlin sur le sujet.

Sinon,

Si vous souhaitez une API Silverlight native sans proxy, pont ou serveur Web, vous pouvez utiliser Nirvana de my-Channels comme middleware de messagerie. Découvrez Nirvana sur my-Channels et leur site vitrine. (désolé, je suis un nouvel utilisateur et je ne peux pas soumettre de liens):

Alex

EDIT: cela fonctionne vraiment bien. Je me suis fait mordre par la " variable cachée " dans une fermeture: (

J'ai utilisé le PollingDuplex pour SL2 et je pense qu'il n'est pas encore prêt pour la production.

Mon problème principal est le fait qu'il ne discrimine pas les clients sur le même ordinateur. Si j’exécute 2 clients, l’un d’eux ne pourra plus interroger le serveur et mourra. Il existe un identifiant de session différent pour les 2 clients, mais il est simplement ignoré du côté client.

De même, si je tue un client, puis en crée un nouveau, le nouveau client recevra les mises à jour push du client précédent pendant un certain temps.

Quelqu'un at-il rencontré les mêmes problèmes ou est-il résolu dans SL3?

En fait, j’ai lancé quelques autres codes de démonstration et me suis rendu compte que, pour une raison quelconque, vous devez spécifier InstanceContextMode et InstanceMode afin que le service soit basé sur une session et non sur un singleton (pour autant que je sache). Le code de démonstration simple que j'ai extrait pose clairement des problèmes de performances.

Il est regrettable que ce comportement n'ait pas été documenté.

Mon organisation a constaté que la mise en œuvre de Silverlight 2.0 / WCF était un peu "pas prête pour les heures de grande écoute", du moins pour ce pour quoi nous avions prévu de l'utiliser.

Nous avons finalement opté pour XMPP / Jabber, car c’est une bête plus bien formée, et vous pouvez l’implémenter assez facilement dans Silverlight, en récupérant simplement des ressources sur Internet.

Je suis convaincu que Silverlight 3.0 implémentera une implémentation Push plus récente / mieux formée, à partir des informations disponibles publiquement.

PollingDuplexHttpBinding est probablement la manière la plus élégante de le faire.

Une alternative moins impliquée consiste à utiliser un socket TCP à partir de votre client Silverlight. Chaque fois que l'un des clients Silverlight doit faire l'objet d'une mise à jour, vous pouvez lui envoyer un message TCP contenant le nom du service WCF à appeler ou toute autre information plus légère.

J'utilise cette approche pour une application et cela fonctionne bien.

Une solution beaucoup plus simple et plus puissante sur le site http: //www.udaparts .com / document / Tutorial / slpush.htm

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top