WCF-service gebruiken via TCP-transport in Silverlight 4
In dit artikel wordt beschreven hoe u de WCF-service (Windows Communication Foundation) gebruikt via TCP-transport (Transmission Control Protocol) in Microsoft Silverlight 4.
Oorspronkelijke productversie: Silverlight
Origineel KB-nummer: 2425652
Samenvatting
Silverlight 4 ondersteunt een netTcp-transportbindingselement dat ons een nieuwe keuze geeft om duplex WCF te implementeren. In dit codevoorbeeld ziet u hoe u netTcp WCF in Silverlight gebruikt door een weerrapportabonnement te maken.
Om te laten zien dat Silverlight toegang heeft tot WCF, hebt u mogelijk een WCF-service en een Silverlight WCF-client nodig. Volg deze drie stappen om een weerrapportabonnement te maken:
Stap 1: Een Duplex WCF-service maken met NetTcpBinding
Maak een nieuw consoleproject
NetTcpWCFService
. Voeg vervolgens een nieuwe WCF-serviceWeatherService
toe aan het project.Open een IWeatherService.cs-bestand en voer de volgende code uit om het servicecontract te definiƫren:
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); } }
Open een WeatherService.cs-bestand en gebruik statische gebeurtenisbenadering om de abonnementsservice te implementeren. U moet eerst het
ServiceBehavior
kenmerk voorvoegsel toevoegen aan de bestaandeWeatherService
klasse en eenInstanceContext
modus instellen op eenPerSession
service. Voer vervolgens de volgende code uit om de standaardinhoud van deWeatherService
klasse te vervangen:[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;} }
Maak een afzonderlijke thread om periodiek een mock-weerrapport te genereren. Voer de volgende code uit om de
System.Threading
naamruimte toe te voegen in een statische constructor van deWeatherService
klasse: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)] }); } }) ); }
Als u een
netTcpbinding
eindpunt wilt toevoegen aan de WCF-service, voert u de volgende code uit om een app.configte configureren:<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>
Opmerking
Slechts enkele poorten tussen 4502 en 4534 mogen worden geopend door Silverlight en u hebt een clienttoegangsbeleidsbestand nodig om Silverlight-toegang toe te staan. Raadpleeg Stap 3 voor meer informatie over het toestaan van silverlight-toegang.
Open een Program.cs-bestand en voeg een naamruimte
System.ServiceModel
toe. Voer de volgende code uit om eenServiceHost
service te starten inMain
de methode: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(); } }
Stap 2: Een Silverlight WCF-client maken
Maak een Silverlight-toepassing om de WCF te gebruiken. U hebt een knop nodig om de service te abonneren of af te melden en een keuzelijst om het weerrapport van de service weer te geven.
Maak een nieuw Silverlight-project CSSL4WCFNetTcp. In het dialoogvenster Nieuwe Silverlight-toepassing moet u het selectievakje De Silverlight-toepassing hosten op een nieuwe website inschakelen en vervolgens de Silverlight-versie instellen op Silverlight 4.
Voer de volgende code uit om een MainPage.xaml-bestand te openen en het standaardrasterelement te bewerken:
<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>
Voeg een servicereferentie toe aan de klasse in de
weatherService
WCF-service. Hiervoor stelt u het project NetTcpWCFService in als opstartproject en drukt u op Ctrl+F5 om de service te starten. Klik vervolgens met de rechtermuisknop op het Silverlight-project, selecteer de optie Serviceverwijzing toevoegen , voer in het dialoogvenster Serviceverwijzing toevoegen het adres van de weerservice in en druk op OK. En vervolgens genereert Visual Studio 2010 WCF-proxycode in het Silverlight-project.Voer de volgende code uit om het MainPage.xaml.cs-bestand te openen en initialiseer de WCF-proxy in
Loaded
het geval: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) }); } }
Voer de volgende code uit om een gebeurtenis-handler toe te voegen aan de knop Klik op gebeurtenis:
private void Button_Click(object sender, RoutedEventArgs e) { if (!_subscribed) { _client.SubscribeAsync(); } else { _client.UnSubscribeAsync(); } btnSubscribe.IsEnabled = false; }
Stap 3: Beleidsbestand voor meerdere domeinen implementeren
Maak een XML-bestand clientaccesspolicy.xml, gebruik de volgende code om inhoud te configureren:
<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>
Opmerking
Dit bestand verleent machtigingen aan de Silverlight-clients die afkomstig zijn van een domein voor toegang tot de serverpoorten tussen 4502 en 4506.
Zoek het pad naar de fysieke hoofdmap (standaard,
C:\inetpub\wwwroot
als u IIS gebruikt) van de serverwebsite en plaats het beleidsbestand in het pad.