Utiliser le service WCF sur le transport TCP dans Silverlight 4

Cet article explique comment utiliser le transport tcp (Service WCF) Windows Communication Foundation (Windows Communication Foundation) dans Microsoft Silverlight 4.

Version d’origine du produit : Silverlight
Numéro de la base de connaissances d’origine : 2425652

Résumé

Silverlight 4 prend en charge un élément de liaison de transport netTcp qui nous offre un nouveau choix pour implémenter wcf duplex. Cet exemple de code montre comment utiliser netTcp WCF dans Silverlight en créant un abonnement aux rapports météorologiques.

Pour illustrer l’accès de Silverlight à WCF, vous aurez peut-être besoin d’un service WCF et d’un client WCF Silverlight. Pour créer une application d’abonnement aux rapports météorologiques, procédez comme suit :

Étape 1 : Créer un service WCF duplex avec NetTcpBinding

  1. Créez un projet NetTcpWCFServicede console . Ajoutez ensuite un nouveau service WeatherService WCF au projet.

  2. Ouvrez un fichier IWeatherService.cs , exécutez le code suivant pour définir le contrat de service :

     namespace NetTcpWCFService
    {
        [ServiceContract(CallbackContract=typeof(IWeatherServiceCallback))]
        public interface IWeatherService
        {
            [OperationContract(IsOneWay = true)]
            void Subscribe();
                [OperationContract(IsOneWay = true)]
            void UnSubscribe();
        }
        public interface IWeatherServiceCallback
        {
            [OperationContract(IsOneWay=true)]
            void WeatherReport(string report);
        }
    }
    
  3. Ouvrez un fichier WeatherService.cs , utilisez l’approche d’événement statique pour implémenter le service d’abonnement. Vous devez d’abord préfixer l’attribut ServiceBehavior sur la classe existante WeatherService , puis définir un InstanceContext mode sur un PerSession service. Ensuite, exécutez le code suivant pour remplacer le contenu par défaut de la WeatherService classe :

    [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
        public class WeatherService : IWeatherService
        {
            static event EventHandler<WeatherEventArgs> WeatherReporting;
            IWeatherServiceCallback _callback;
            public void Subscribe()
            {
                _callback = OperationContext.Current.GetCallbackChannel<IWeatherServiceCallback>();
                WeatherReporting += new EventHandler<WeatherEventArgs>(WeatherService_WeatherReporting);
            }
            public void UnSubscribe()
            {
                WeatherReporting -= new EventHandler<WeatherEventArgs>(WeatherService_WeatherReporting);
            }
            void WeatherService_WeatherReporting(object sender, WeatherEventArgs e)
            {
                // Remember check the callback channel's status before using it.
                if (((ICommunicationObject)_callback).State == CommunicationState.Opened)
                    _callback.WeatherReport(e.WeatherReport);
                else
                    UnSubscribe();
            }
        }
        class WeatherEventArgs:EventArgs
        {
            public string WeatherReport{set;get;}
        }
    
  4. Créez un thread distinct pour générer régulièrement un rapport météo fictif. Exécutez le code suivant pour ajouter l’espace System.Threading de noms, dans un constructeur statique de la WeatherService classe :

    static WeatherService()
    {
        ThreadPool.QueueUserWorkItem
        (
            new WaitCallback(delegate
            {
                string[] weatherArray = { "Sunny", "Windy", "Snow", "Rainy" };
                Random rand = new Random();
    
                while (true)
                {
                    Thread.Sleep(1000);
                    if (WeatherReporting != null)
                        WeatherReporting(
                            null,
                            new WeatherEventArgs
                            {
                                WeatherReport = weatherArray[rand.Next(weatherArray.Length)]
                            });
                }
            })
        );
    }
    
  5. Pour ajouter un netTcpbinding point de terminaison au service WCF, exécutez le code suivant pour configurer un app.config:

     <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="NetTcpWCFService.WeatherServiceBehavior">
                    <serviceMetadata />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service behaviorConfiguration="NetTcpWCFService.WeatherServiceBehavior"
                name="NetTcpWCFService.WeatherService">
                <endpoint address="" binding="netTcpBinding" bindingConfiguration="b1"
                  contract="NetTcpWCFService.IWeatherService" />
                <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="net.tcp://localhost:4504/WeatherService" />
                    </baseAddresses>
                </host>
            </service>
        </services>
            <bindings>
                <netTcpBinding>
                    <binding name="b1">
                        <security mode="None"/>
                    </binding>
                </netTcpBinding>
            </bindings>
    </system.serviceModel>
    

    Remarque

    Seuls quelques ports allant de 4502 à 4534 sont autorisés à être accessibles par Silverlight, et vous avez besoin d’un fichier de stratégie d’accès client pour autoriser l’accès Silverlight. Pour plus d’informations sur l’autorisation de l’accès Silverlight, reportez-vous à l’étape 3.

  6. Ouvrez un fichier Program.cs , ajoutez un espace de noms System.ServiceModel. Exécutez le code suivant pour démarrer un ServiceHost service dans la Main méthode :

    static void Main(string[] args)
    {
        using (var host = new ServiceHost(typeof(WeatherService)))
        {
            host.Open();
            Console.WriteLine("Service is running...");
            Console.WriteLine("Service address: "+host.BaseAddresses[0]);
            Console.Read();
        }
    }
    

Étape 2 : Créer un client WCF Silverlight

Créez une application Silverlight pour consommer WCF. Vous avez besoin d’un bouton pour vous abonner ou de vous désabonner du service, et d’une zone de liste pour afficher le rapport météorologique du service.

  1. Créez un projet Silverlight CSSL4WCFNetTcp. Dans la boîte de dialogue Nouvelle application Silverlight, vous devez case activée la case Héberger l’application Silverlight dans un nouveau site web, puis définir la version silverlight sur Silverlight 4.

  2. Exécutez le code suivant pour ouvrir un fichier MainPage.xaml et modifier l’élément Grid par défaut :

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="46*" />
            <RowDefinition Height="26*" />
            <RowDefinition Height="228*" />
        </Grid.RowDefinitions>
        <TextBlock Text="Silverlight NetTcp Sample" Grid.Row="0" Margin="0,0,0,10" FontSize="24"/>
        <StackPanel Orientation="Horizontal" Grid.Row="1">
            <Button Content="Subscribe weather report" Name="btnSubscribe" Click="Button_Click"/>
            <TextBlock VerticalAlignment="Center" FontStyle="Italic" Foreground="Red" Margin="5,0,0,0" Name="tbInfo"/>
        </StackPanel>
        <ListBox Name="lbWeather" Grid.Row="2" Margin="0,5,0,0"/>
    </Grid>
    
  3. Ajoutez une référence de service à la classe dans le weatherService service WCF. Pour ce faire, définissez le projet NetTcpWCFService comme projet de démarrage, appuyez sur Ctrl+F5 pour démarrer le service. Ensuite, cliquez avec le bouton droit sur le projet Silverlight, sélectionnez l’option Ajouter une référence de service , dans la boîte de dialogue Ajouter une référence de service , entrez l’adresse du service météo, puis appuyez sur OK. Ensuite, Visual Studio 2010 génère du code proxy WCF dans le projet Silverlight.

  4. Exécutez le code suivant pour ouvrir le fichier MainPage.xaml.cs et initialiser le proxy WCF dans Loaded l’événement :

    public partial class MainPage : UserControl,IWeatherServiceCallback
    {
        public MainPage()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }
        bool _subscribed;
        WeatherServiceClient _client;
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            _client = new WeatherServiceClient(
                new System.ServiceModel.InstanceContext(this));
            _client.SubscribeCompleted += _client_SubscribeCompleted;
            _client.UnSubscribeCompleted += _client_UnSubscribeCompleted;
        }
        void _client_UnSubscribeCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                _subscribed = false;
                btnSubscribe.Content = "Subscribe weather report";
                tbInfo.Text = "";
            }else
                tbInfo.Text = "Unable to connect to service.";
            btnSubscribe.IsEnabled = true;
        }
        void _client_SubscribeCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                _subscribed = true;
                btnSubscribe.Content = "UnSubscribe weather report";
                tbInfo.Text = "";
            }
            else
                tbInfo.Text="Unable to connect to service.";
            btnSubscribe.IsEnabled = true;
        }
        // Display report when callback channel get called.
        public void WeatherReport(string report)
        {
            lbWeather.Items.Insert(
                0,
                new ListBoxItem
                {
                    Content = string.Format("{0} {1}",DateTime.Now, report)
                });
        }
    }
    
  5. Exécutez le code suivant pour ajouter un gestionnaire d’événements afin de gérer l’événement de clic de bouton :

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (!_subscribed)
        {
            _client.SubscribeAsync();
        }
        else
        {
            _client.UnSubscribeAsync();
        }
        btnSubscribe.IsEnabled = false;
    }
    

Étape 3 : Déploiement d’un fichier de stratégie inter-domaines

  1. Créez un fichier xml clientaccesspolicy.xml, utilisez le code suivant pour configurer le contenu :

    <access-policy>
        <cross-domain-access>
            <policy>
                <allow-from>
                    <domain uri="*"/>
                </allow-from>
                <grant-to>
                    <socket-resource port="4502-4506" protocol="tcp" />
                </grant-to>
            </policy>
        </cross-domain-access>
    </access-policy>
    

    Remarque

    Ce fichier accorde des autorisations aux clients Silverlight provenant de n’importe quel domaine pour accéder aux ports de serveur compris entre 4502 et 4506.

  2. Recherchez le chemin d’accès du répertoire physique racine (par défaut, C:\inetpub\wwwroot si vous utilisez IIS) du site web du serveur, placez le fichier de stratégie dans le chemin d’accès.