Silverlight 4'te TCP aktarımı üzerinden WCF hizmetini kullanma

Bu makalede, Microsoft Silverlight 4'te İletim Denetimi Protokolü (TCP) üzerinden Windows Communication Foundation (WCF) Hizmeti'nin nasıl tüketilmesi açıklanır.

Orijinal ürün sürümü: Silverlight
Özgün KB numarası: 2425652

Özet

Silverlight 4, çift yönlü WCF uygulamak için yeni bir seçenek sunan netTcp aktarım bağlama öğesini destekler. Bu kod örneği, bir hava durumu raporu aboneliği oluşturarak Silverlight'ta netTcp WCF'nin nasıl tükettiğini gösterir.

Silverlight'ın WCF'ye erişimini göstermek için bir WCF hizmetine ve Silverlight WCF istemcisine ihtiyacınız olabilir. Hava durumu raporu abonelik uygulaması oluşturmak için şu üç adımı izleyin:

1. Adım: NetTcpBinding ile Çift Yönlü WCF hizmeti oluşturma

  1. Yeni bir konsol projesi NetTcpWCFServiceoluşturun. Ardından projeye yeni bir WCF Hizmeti WeatherService ekleyin.

  2. bir IWeatherService.cs dosyası açın, hizmet sözleşmesini tanımlamak için aşağıdaki kodu çalıştırın:

     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. bir WeatherService.cs dosyası açın, abonelik hizmetini uygulamak için statik olay yaklaşımını kullanın. Önce özniteliğin ön ekini ServiceBehavior mevcut WeatherService sınıfa eklemeniz, bir InstanceContext modu bir PerSession hizmete ayarlamanız gerekir. Ardından aşağıdaki kodu çalıştırarak sınıfın varsayılan içeriğini WeatherService değiştirin:

    [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. Düzenli aralıklarla sahte hava durumu raporu oluşturmak için ayrı bir iş parçacığı oluşturun. Sınıfın statik oluşturucusunda System.ThreadingWeatherService ad alanını eklemek için aşağıdaki kodu çalıştırın:

    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. WCF hizmetine uç netTcpbinding nokta eklemek için aşağıdaki kodu çalıştırarak birapp.configyapılandırın:

     <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>
    

    Not

    Silverlight tarafından yalnızca 4502 ile 4534 arasında olan birkaç bağlantı noktası erişilebilir ve Silverlight erişimine izin vermek için bir istemci erişim ilkesi dosyasına ihtiyacınız vardır. Silverlight erişimine izin verme hakkında daha fazla bilgi için lütfen 3. Adım'a bakın.

  6. bir Program.cs dosyası açın, ad alanı System.ServiceModelekleyin. Yönteminde Main bir ServiceHost hizmeti başlatmak için aşağıdaki kodu çalıştırın:

    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();
        }
    }
    

2. Adım: Silverlight WCF istemcisi oluşturma

WCF'yi kullanmak için bir Silverlight uygulaması oluşturun. Hizmete abone olmak veya aboneliği kaldırmak için bir düğmeye ve hizmetten hava durumu raporunu görüntülemek için bir liste kutusuna ihtiyacınız vardır.

  1. Yeni bir Silverlight projesi CSSL4WCFNetTcp oluşturun. Yeni Silverlight Uygulaması iletişim kutusunda, Silverlight uygulamasını yeni bir Web sitesinde barındır onay kutusunu işaretlemeniz ve silverlight sürümünü Silverlight 4 olarak ayarlamanız gerekir.

  2. MainPage.xaml dosyasını açmak ve varsayılan Grid öğesini düzenlemek için aşağıdaki kodu çalıştırın:

    <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. WCF hizmetindeki sınıfına weatherService bir Hizmet Başvurusu ekleyin. Bunu yapmak için NetTcpWCFService projesini başlangıç projesi olarak ayarlayın, hizmeti başlatmak için Ctrl+F5 tuşlarına basın. Ardından Silverlight projesine sağ tıklayın, Hizmet Başvurusu Ekle seçeneğini belirleyin, Hizmet Başvurusu Ekle iletişim kutusunda weatherservice adresini girin ve Tamam'a basın. Ardından Visual Studio 2010, Silverlight projesinde WCF proxy kodu oluşturur.

  4. aşağıdaki kodu çalıştırarak MainPage.xaml.cs dosyasını açın ve olayda WCF proxy'sini Loaded başlatın:

    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. Düğme tıklama olayını işlemek üzere bir olay işleyicisi eklemek için aşağıdaki kodu çalıştırın:

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

3. Adım: Etki alanları arası ilke dosyasını dağıtma

  1. clientaccesspolicy.xmlbir xml dosyası oluşturun, içeriği yapılandırmak için aşağıdaki kodu kullanın:

    <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>
    

    Not

    Bu dosya, herhangi bir etki alanından gelen Silverlight istemcilerine 4502 ile 4506 arasında olan sunucu bağlantı noktalarına erişim izinleri verir.

  2. Sunucu web sitesinin kök fiziksel dizininin yolunu (varsayılan olarak C:\inetpub\wwwroot IIS kullanıyorsanız) bulun, ilke dosyasını yola yerleştirin.