Procedimiento para crear un servicio que requiere sesiones
Las sesiones crean un estado compartido entre dos o más extremos que habilita características útiles como las devoluciones de llamada, la seguridad de saltos múltiples y asociaciones entre clientes e instancias de servicio. Para obtener más información sobre las sesiones en aplicaciones Windows Communication Foundation (WCF), consulte Uso de sesiones.
Especificar que un contrato requiere su enlace para admitir sesiones
Crear un contrato de servicio que contenga al menos una operación. Para obtener un ejemplo de cómo crear un contrato de servicio, consulte Procedimiento para definir un contrato de servicio.
Modifique el System.ServiceModel.ServiceContractAttribute que declara el contrato estableciendo la propiedad ServiceContractAttribute.SessionMode en:
SessionMode.Required si este contrato se debe ejecutar dentro de una sesión.
SessionMode.Allowed si este contrato puede ejecutarse dentro de una sesión.
SessionMode.NotAllowed si este contrato no se debe ejecutar dentro de una sesión.
Configure su extremo de servicio para que use un enlace que admita sesiones. El siguiente ejemplo de configuración muestra el uso de System.ServiceModel.WSDualHttpBinding, que admite una sesión WS
-
ReliableMessaging.<appSettings> <!-- use appSetting to configure base address provided by host --> <add key="baseAddress" value="http://localhost:8080/ServiceMetadata" /> </appSettings> <system.serviceModel> <services> <service name="Microsoft.WCF.Documentation.DuplexHello" behaviorConfiguration="mex" > <endpoint address="/DuplexService" binding="wsDualHttpBinding" contract="Microsoft.WCF.Documentation.IDuplexHello" /> <endpoint address="" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="mex" > <serviceMetadata httpGetEnabled="true" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
Ejemplo
El siguiente código de ejemplo muestra cómo especificar un requisito de sesión del nivel de contrato y utilizar un archivo de configuración para admitir ese requisito con el enlace System.ServiceModel.WSDualHttpBinding.
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading;
namespace Microsoft.WCF.Documentation
{
[ServiceContract(
Name = "SampleDuplexHello",
Namespace = "http://microsoft.wcf.documentation",
CallbackContract = typeof(IHelloCallbackContract),
SessionMode = SessionMode.Required
)]
public interface IDuplexHello
{
[OperationContract(IsOneWay = true)]
void Hello(string greeting);
}
public interface IHelloCallbackContract
{
[OperationContract(IsOneWay = true)]
void Reply(string responseToGreeting);
}
[ServiceBehaviorAttribute(InstanceContextMode=InstanceContextMode.PerSession)]
public class DuplexHello : IDuplexHello
{
public DuplexHello()
{
Console.WriteLine("Service object created: " + this.GetHashCode().ToString());
}
~DuplexHello()
{
Console.WriteLine("Service object destroyed: " + this.GetHashCode().ToString());
}
public void Hello(string greeting)
{
Console.WriteLine("Caller sent: " + greeting);
Console.WriteLine("Session ID: " + OperationContext.Current.SessionId);
Console.WriteLine("Waiting two seconds before returning call.");
// Put a slight delay to demonstrate asynchronous behavior on client.
Thread.Sleep(2000);
IHelloCallbackContract callerProxy
= OperationContext.Current.GetCallbackChannel<IHelloCallbackContract>();
string response = "Service object " + this.GetHashCode().ToString() + " received: " + greeting;
Console.WriteLine("Sending back: " + response);
callerProxy.Reply(response);
}
}
}
Imports System.Collections.Generic
Imports System.ServiceModel
Imports System.Threading
Namespace Microsoft.WCF.Documentation
<ServiceContract(Name:="SampleDuplexHello", Namespace:="http://microsoft.wcf.documentation", _
CallbackContract:=GetType(IHelloCallbackContract), SessionMode:=SessionMode.Required)> _
Public Interface IDuplexHello
<OperationContract(IsOneWay:=True)> _
Sub Hello(ByVal greeting As String)
End Interface
Public Interface IHelloCallbackContract
<OperationContract(IsOneWay:=True)> _
Sub Reply(ByVal responseToGreeting As String)
End Interface
<ServiceBehaviorAttribute(InstanceContextMode:=InstanceContextMode.PerSession)> _
Public Class DuplexHello
Implements IDuplexHello
Public Sub New()
Console.WriteLine("Service object created: " & Me.GetHashCode().ToString())
End Sub
Protected Overrides Sub Finalize()
Console.WriteLine("Service object destroyed: " & Me.GetHashCode().ToString())
End Sub
Public Sub Hello(ByVal greeting As String) Implements IDuplexHello.Hello
Console.WriteLine("Caller sent: " & greeting)
Console.WriteLine("Session ID: " & OperationContext.Current.SessionId)
Console.WriteLine("Waiting two seconds before returning call.")
' Put a slight delay to demonstrate asynchronous behavior on client.
Thread.Sleep(2000)
Dim callerProxy As IHelloCallbackContract = OperationContext.Current.GetCallbackChannel(Of IHelloCallbackContract)()
Dim response = "Service object " & Me.GetHashCode().ToString() & " received: " & greeting
Console.WriteLine("Sending back: " & response)
callerProxy.Reply(response)
End Sub
End Class
End Namespace
<appSettings>
<!-- use appSetting to configure base address provided by host -->
<add key="baseAddress" value="http://localhost:8080/ServiceMetadata" />
</appSettings>
<system.serviceModel>
<services>
<service
name="Microsoft.WCF.Documentation.DuplexHello"
behaviorConfiguration="mex"
>
<endpoint
address="/DuplexService"
binding="wsDualHttpBinding"
contract="Microsoft.WCF.Documentation.IDuplexHello"
/>
<endpoint
address=""
binding="mexHttpBinding"
contract="IMetadataExchange"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="mex" >
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>