Consumir serviço WCF por meio do transporte TCP no Silverlight 4
Este artigo descreve como consumir o transporte TCP (Protocolo de Controle de Transmissão) do Windows Communication Foundation (WCF) no Microsoft Silverlight 4.
Versão original do produto: Silverlight
Número de KB original: 2425652
Resumo
O Silverlight 4 dá suporte a um elemento de associação de transporte netTcp que nos dá uma nova opção para implementar o WCF duplex. Este exemplo de código demonstra como consumir netTcp WCF em Silverlight criando uma assinatura de relatório meteorológico.
Para demonstrar o acesso do Silverlight ao WCF, talvez seja necessário um serviço WCF e um cliente Silverlight WCF. Para criar um aplicativo de assinatura de relatório meteorológico, siga estas três etapas:
Etapa 1: criar um serviço duplex WCF com NetTcpBinding
Crie um novo projeto
NetTcpWCFService
de console . Em seguida, adicione um novo ServiçoWeatherService
WCF ao projeto.Abra um arquivo IWeatherService.cs , execute o seguinte código para definir o contrato de serviço:
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); } }
Abra um arquivo WeatherService.cs , use a abordagem de evento estático para implementar o serviço de assinatura. Primeiro, você precisa prefixar o
ServiceBehavior
atributo para a classe existenteWeatherService
, definir umInstanceContext
modo como umPerSession
serviço. Em seguida, execute o seguinte código para substituir o conteúdo padrão daWeatherService
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;} }
Crie um thread separado para gerar um relatório meteorológico simulado periodicamente. Execute o seguinte código para adicionar o
System.Threading
namespace em um construtor estático daWeatherService
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)] }); } }) ); }
Para adicionar um ponto de
netTcpbinding
extremidade ao serviço WCF, execute o seguinte código para configurar um 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>
Observação
Apenas algumas portas que são de 4502 a 4534 têm permissão para serem acessadas pelo Silverlight, e você precisa de um arquivo de política de acesso ao cliente para permitir o acesso ao Silverlight. Para obter mais informações sobre como permitir o acesso ao Silverlight, consulte a Etapa 3.
Abra um arquivo Program.cs , adicione um namespace
System.ServiceModel
. Execute o seguinte código para iniciar umServiceHost
serviço noMain
método: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(); } }
Etapa 2: criar um cliente WCF silverlight
Crie um aplicativo Silverlight para consumir o WCF. Você precisa de um botão para assinar ou cancelar assinatura do serviço e uma caixa de listagem para exibir o relatório meteorológico do serviço.
Crie um novo projeto silverlight CSSL4WCFNetTcp. Na caixa de diálogo Novo Aplicativo Silverlight, você precisa marcar o aplicativo Host the Silverlight em uma nova caixa de seleção do site e, em seguida, definir a Versão Silverlight como Silverlight 4.
Execute o seguinte código para abrir um arquivo MainPage.xaml e editar o elemento grid padrão:
<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>
Adicione uma referência de serviço à
weatherService
classe no serviço WCF. Para fazer isso, defina o projeto NetTcpWCFService como um projeto de inicialização, pressione Ctrl+F5 para iniciar o serviço. Em seguida, clique com o botão direito do mouse no projeto Silverlight, selecione Adicionar Referência de Serviço , na caixa de diálogo Adicionar Referência de Serviço , insira o endereço do serviço meteorológico e pressione OK. E, em seguida, o Visual studio 2010 gera o código proxy do WCF no projeto Silverlight.Execute o seguinte código para abrir o arquivo MainPage.xaml.cs e Inicializar o proxy WCF no
Loaded
evento: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) }); } }
Execute o seguinte código para adicionar um manipulador de eventos para manipular o evento clique no botão:
private void Button_Click(object sender, RoutedEventArgs e) { if (!_subscribed) { _client.SubscribeAsync(); } else { _client.UnSubscribeAsync(); } btnSubscribe.IsEnabled = false; }
Etapa 3: Implantação de arquivo de política de domínio cruzado
Crie um arquivo xml clientaccesspolicy.xml, use o seguinte código para configurar o conteúdo:
<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>
Observação
Esse arquivo concede permissões aos clientes Silverlight que são de qualquer domínio para acessar as portas do servidor entre 4502 e 4506.
Descubra o caminho do diretório físico raiz (por padrão,
C:\inetpub\wwwroot
se você usar o IIS) do site do servidor, coloque o arquivo de política no caminho.