Enkelriktad
Oneway-exemplet visar en tjänstkontakt med enkelriktade tjänståtgärder. Klienten väntar inte på att tjänståtgärderna ska slutföras, vilket är fallet med tvåvägstjänståtgärder. Det här exemplet baseras på komma igång och använder bindningen wsHttpBinding
. Tjänsten i det här exemplet är ett lokalt konsolprogram som gör att du kan observera tjänsten som tar emot och bearbetar begäranden. Klienten är också ett konsolprogram.
Kommentar
Installationsproceduren och bygginstruktionerna för det här exemplet finns i slutet av det här avsnittet.
Om du vill skapa ett envägstjänstkontrakt definierar du ditt tjänstkontrakt, tillämpar OperationContractAttribute klassen på varje åtgärd och anger IsOneWay till true
enligt följande exempelkod:
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOneWayCalculator
{
[OperationContract(IsOneWay=true)]
void Add(double n1, double n2);
[OperationContract(IsOneWay = true)]
void Subtract(double n1, double n2);
[OperationContract(IsOneWay = true)]
void Multiply(double n1, double n2);
[OperationContract(IsOneWay = true)]
void Divide(double n1, double n2);
}
För att visa att klienten inte väntar på att tjänståtgärderna ska slutföras implementerar tjänstkoden i det här exemplet en fördröjning på fem sekunder, enligt följande exempelkod:
// This service class implements the service contract.
// This code writes output to the console window.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerCall)]
public class CalculatorService : IOneWayCalculator
{
public void Add(double n1, double n2)
{
Console.WriteLine("Received Add({0},{1}) - sleeping", n1, n2);
System.Threading.Thread.Sleep(1000 * 5);
double result = n1 + n2;
Console.WriteLine("Processing Add({0},{1}) - result: {2}", n1, n2, result);
}
...
}
När klienten anropar tjänsten returneras anropet utan att vänta på att tjänståtgärden ska slutföras.
När du kör exemplet visas klient- och tjänstaktiviteterna i både tjänst- och klientkonsolfönstren. Du kan se att tjänsten tar emot meddelanden från klienten. Tryck på RETUR i varje konsolfönster för att stänga av både tjänsten och klienten.
Klienten slutar före tjänsten, vilket visar att en klient inte väntar på att envägstjänståtgärder ska slutföras. Klientutdata är följande:
Add(100,15.99)
Subtract(145,76.54)
Multiply(9,81.25)
Divide(22,7)
Press <ENTER> to terminate client.
Följande tjänstutdata visas:
The service is ready.
Press <ENTER> to terminate service.
Received Add(100,15.99) - sleeping
Received Subtract(145,76.54) - sleeping
Received Multiply(9,81.25) - sleeping
Received Divide(22,7) - sleeping
Processing Add(100,15.99) - result: 115.99
Processing Subtract(145,76.54) - result: 68.46
Processing Multiply(9,81.25) - result: 731.25
Processing Divide(22,7) - result: 3.14285714285714
Kommentar
HTTP är per definition ett protokoll för begäran/svar; när en begäran görs returneras ett svar. Detta gäller även för en enkelriktad tjänståtgärd som exponeras via HTTP. När åtgärden anropas returnerar tjänsten en HTTP-statuskod på 202 innan tjänståtgärden har körts. Den här statuskoden innebär att begäran har godkänts för bearbetning, men bearbetningen har ännu inte slutförts. Klienten som anropade åtgärden blockerar tills den tar emot 202-svaret från tjänsten. Detta kan orsaka ett oväntat beteende när flera enkelriktade meddelanden skickas med en bindning som är konfigurerad för att använda sessioner. Bindningen wsHttpBinding
som används i det här exemplet är konfigurerad att använda sessioner som standard för att upprätta en säkerhetskontext. Som standard kommer meddelanden i en session garanterat att tas emot i den ordning de skickas. När det andra meddelandet i en session skickas bearbetas det därför inte förrän det första meddelandet har bearbetats. Resultatet av detta är att klienten inte får 202-svaret för ett meddelande förrän bearbetningen av föregående meddelande har slutförts. Klienten verkar därför blockera varje efterföljande åtgärdsanrop. För att undvika det här beteendet konfigurerar det här exemplet körningen för att skicka meddelanden samtidigt till distinkta instanser för bearbetning. Exemplet anges InstanceContextMode till PerCall
så att varje meddelande kan bearbetas av en annan instans. ConcurrencyMode är inställd på att Multiple
tillåta att fler än en tråd skickar meddelanden i taget.
Så här konfigurerar du, skapar och kör exemplet
Kontrollera att du har utfört engångsinstallationsproceduren för Windows Communication Foundation-exempel.
Om du vill skapa C# eller Visual Basic .NET-versionen av lösningen följer du anvisningarna i Skapa Windows Communication Foundation-exempel.
Om du vill köra exemplet i en konfiguration med en eller flera datorer följer du anvisningarna i Köra Windows Communication Foundation-exempel.
Kommentar
Kör tjänsten innan du kör klienten och stäng av klienten innan du stänger av tjänsten. Detta undviker ett klientfel när klienten inte kan stänga säkerhetssessionen rent eftersom tjänsten är borta.