WCF TIPS - Como generar una descarga http estándar y hostearla desde un servicio

por maxi  20. septiembre 2010

    Objectivo: Crear un ejemplo de servicio con WCF que permita a un navegador descargar un archivo por http en forma estándar.

    Características del servicio:

    • Self-Host: En este caso va a ser Self-host  en una aplicacion Winforms asi puede ser hosteado en cualquier maquina sin necesidad de configurar un IIS.

    • REST: No se utilizara SOA, ya que REST es más liviano dado que el mensaje no tiene toda la información del Envelope SOAP.

      Streamming: El servicio enviará el archivo en mediante Streamming lo que permite manejar archivos grandes.

    • Multithreading: el servicio no será Single es decir una instancia del servicio atenderá cada llamada, de esta forma el servicio no encolara las solicitudes si no que podrá atender varias descargas al mismo tiempo y a diferentes clientes.

      Lo primero que haremos será crear el contrato, al que llame IDownloadService que contiene el método DownloadFileHttp, el cual recibe el path y el nombre del archivo para descargar y retornara el Stream.

      Esta claro que no es ideal recibir el path del archivo en el servicio, pero lo hice para ejemplificar como recibir varios parametros ya que este servicio utiliza REST por lo cual el servicio recibe los parametros en forma de query string. El atributo WebGet precisamente nos permite definir que el servicio recibira la solicitud mediante una url de la siguiente forma:

                                       DirecciónBase           / download    / path / fileName

      P.e.: http://localhost:9000/DownloadService / download    / C:@mp3  /   tema.mp3

       
           [ServiceContract]
          public interface IDownloadService
          {
              [OperationContract]
              [WebGet(UriTemplate = "download/{path}/{fileName}")]
              Stream DownloadFileHttp(string path, string fileName);
          }
       

      Una vez definido el contrato vamos  a implementarlo de la siguiente manera:

       
        [ServiceBehavior(
              //Cada solicitud crea una nueva instancia de StreamerSvc y se recicla despeus de la llamada 
              //De esta forma las llamadas no se encolan se puede atender a varios clientes
              InstanceContextMode = InstanceContextMode.PerCall,
              //La instancia del servicio es multi threaded
              //Los threads pueden llamar a cualquier operacion del servicio en cualquier momento
              //Multiple implica que le programador tiene que manejar la sincronizacion con locks
              //Pero como el servicio no maneja estados, p.e. variables o atributo de clase no me afecta
              ConcurrencyMode = ConcurrencyMode.Multiple,
              //Esta propiedad hay que setearla en este ejemplo ya que el servicio esta siendo hosteado en una aplicacon Winforms
              //Implica que todas las llamadas al servicio correran en el mismo thread de la UI que creo el servicio (new ServiceHost(...)))
              //La pongo en false para evitar deadlocks ya que por defecto es true
              UseSynchronizationContext = false)]    public class DownloadSvc : IDownloadStream
          {
              public Stream DownloadFileHttp(string path, string fileName)
              {
      //Truco para poder poner el path en la url solo para este ejemplo
                      path = path.Replace("@", @"\");@", @"\");File does not exists!");application/download";content-disposition", string.Format("attachment;filename=\"{0}\"", fileName));
                      fileName = fileName.Replace("
                      path = Path.Combine(path, fileName);
       
                      if (!File.Exists(path))
                      {
                          throw new FaultException("
                      }
              
                      //Abrimos el archivo 
                      var fileStream = File.OpenRead(path);
       
                      //Configurar Headers para el cliente p.e. un browser
                      var headers = WebOperationContext.Current.OutgoingResponse.Headers;
                      WebOperationContext.Current.OutgoingResponse.ContentType = "
                      headers.Add("
                      headers.Add("content-length", fileStream.Length.ToString());
       
               //Retonranos FileStream
                      return fileStream;
              }}
        

      Muy bonito pero para que todo esto funcione correctamente debemos configurar nuestro servicio. Para esto vamos a setear las siguientes entradas en el config:

       
      <?xml version="1.0" encoding="utf-8"?>
      <configuration>
               <system.serviceModel>
                         <bindings>
                                  <mexHttpBinding>
                                            <binding name="MetadataBinding" />
                                  </mexHttpBinding>
                                  <webHttpBinding>
                                            <binding name="DownloadBinding" sendTimeout="00:10:00" maxBufferPoolSize="2147483647"
                                             maxReceivedMessageSize="2147483647" transferMode="Streamed">
                                            </binding>
                                  </webHttpBinding>
                         </bindings>
                         <services>
                                  <service behaviorConfiguration="ServiceBehavior" name="StreamerSvcHost.StreamerSvc">                             
                                            <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="MetadataBinding"
                                             name="MetadataEndpoint" contract="IMetadataExchange" />
                                            <endpoint address="FileSvc" behaviorConfiguration="RestBehavior"
                                             binding="webHttpBinding" bindingConfiguration="DownloadBinding"
                                             name="DownloadEndpoint" contract="StreamerSvcHost.IDownloadService" />
                                            <host>
                                                     <baseAddresses>
                                                              <add baseAddress="http://localhost:9000/" />
                                                     </baseAddresses>
                                            </host>
                                  </service>
                         </services>
                         <behaviors>
                                  <endpointBehaviors>
                                            <behavior name="RestBehavior">
                                                     <webHttp />
                                            </behavior>
                                  </endpointBehaviors>
                                  <serviceBehaviors>
                                            <behavior name="ServiceBehavior">
                                                     <serviceMetadata httpGetEnabled="true" />
                                                     <serviceDebug includeExceptionDetailInFaults="true" />
                                                     <dataContractSerializer maxItemsInObjectGraph="2147483647" />
                                            </behavior>
                                  </serviceBehaviors>
                         </behaviors>
               </system.serviceModel>

      </configuration>

       

        Lo destacable es lo siguiente:

        • El endpoint deberá tener un webHttpBinding, esto permite exponer el servicio para ser accedido mediante HTTP requests  en lugar de mensajes SOAP.

        • El binding se deberá configurar con TransferMode = Streamed

        • El endpoint deberá tener configura un EndpointBehavior agregándole le elemento webHttp, para que un cliente pueda comunicarse por http con el servicio este debe tener asociado este comportamiento.

        Tags: , , , , , ,

        WCF

        WCF Tips - Enum definirlo en el servicio y utilizarlo en el cliente

        por maxi  14. septiembre 2010

        Para utilizar un enum simplemente lo definimos y agregamos el atributo DataContract. A cada valor del enum le definimos el atributo EnumMember.

        De esta forma si este enum se recibe como parámetro o es retornado por un metodo del servicio, se generará en la referencia al servicio del cliente.

         

            [DataContract]
        public enum CodigosMovEnum
        {
        [EnumMember]
        Ninguno = 0,

        [EnumMember]
        AEntregar = 1,

        [EnumMember]
        ACumplir = 2,

        }

        Tags: ,

        WCF

        Que hay de nuevo en VS2010?

        por Daniel Laco  4. marzo 2010

        Ya se viene la liberación de la versión final de Visual Studio 2010 y .NET 4.0 y uno siempre quiere tener una vista rápida de los cambios, agregados, etc.

        En http://msdn.microsoft.com/en-us/library/bb386063(VS.100).aspx pueden encontrar un listado de todos los temas nuevos de esta plataforma.

         

        Tags: , , , ,

        .NET | ADO.NET | ASP.NET | Entity Framework | Visual Studio | WCF | WinForms

        Como cerrar correctamente un proxy WCF

        por Emmanuel  17. marzo 2009
        Teniendo en cuenta que un proxy WCF se deriva de ClientBase<TChannel>, y que éste implementa IDisposable, la mejor manera de utilizarlo pareciera ser:
               try
               {
                   using (var proxy = ProxyFactory.ObtenerProxy())
                   {
                       //Utilizar el proxy
                   }
               }
               catch (Exception ex)
               {
                   throw;
               }
         
        Esta forma de utilización puede llevarnos a un error WCF cuando ocurre una excepción y el canal queda en estado “Faulted”, impidiendo cerrar el proxy.
         
        Si accedemos por Reflection a la implementación de IDisposable observamos:
         
               void IDisposable.Dispose()
               {
                   this.Close();
               }
         
        Esta implementación no contempla el estado del proxy antes de llamar a Close(), de manera que ante cualquier error ocurrido al intentar cerrar el proxy recibiremos una excepción.
         
        Una manera de corregir este comportamiento es creando una extensión:
         
               public static void CloseExt(this SvcClient proxy)
               {
                  if (proxy != null)
                  {
                      var checkClosedState =
                          CommunicationState.Closed | CommunicationState.Closing;
         
                      if (proxy.State == CommunicationState.Faulted)
                      {
                          proxy.Abort();
                      }
                      else if (proxy.State != checkClosedState)
                      {
                          proxy.Close();
                      }
                  }
              }
         
        Y para utilizar la extensión el código se modificaría a:
         
                 SvcClient proxy = null;
         
                try
                {
                   proxy = ProxyFactory.ObtenerProxy;
         
                   //Utilizar el proxy
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    proxy.CloseExt();
                }
         
        De esta manera siempre se llama a la extensión CloseExt(), la que se encarga de cerrar o abortar el proxy según su estado, impidiendo que se genere una excepción por intentar cerrar un proxy en estado “Faulted”.

         

         

        Tags:

        WCF

        Introducción a WCF - Parte 5

        por Maxi Guillén - Daniel Laco  9. febrero 2007

        Introducción a Windows Communication Foundation

        PARTE 5

        Otras Facilidades de WCF

        Transacciones

        WCF nos brinda la posibilidad de realizar transacciones con los servicios. Estas transacciones pueden también ser distribuidas, cuando se comparten con más de un servicio.

        Para habilitar las transacciones:

        • Necesitamos utilizar un Binding adecuado
        • Seleccionar el protocolo (WS-AtomicTransacction , OLE Transactions)
        • Es posible configurar Timeouts y Niveles de Aislamiento utilizando parámetros de ServiceBehavior
        • Habilitar las funcionalidades de transacciones y el comportamiento al completarse la transacción utilizando parámetros de OperationBehavior
        • Podemos tener acceso al contexto de la transacción mediante la propiedad “Transaction.Current”

         

         

        Ejemplo de Transacción:

        En el servicio:

        [ServiceContract(SessionMode = SessionMode.Required)]
        [BindingRequirements(
        TransactionFlowRequirements = RequirementsMode.Required)]
        public interface IClienteManager
        {
                [OperationContract()]
                [TransactionFlow(TransactionFlowOption.Allowed)]
                List<Cliente> DameClientes();
        
                [OperationContract()]
                [TransactionFlow(TransactionFlowOption.Allowed)]
                void ModificarCliente(int id, 
                string nuevoNombre, string nuevoApellido);
        
                [OperationContract()]
                Cliente BuscarCliente(int id);
        }
         
        [ServiceBehavior(TransactionIsolationLevel = 
        System.Transactions.IsolationLevel.ReadUncommitted,
         InstanceContextMode = InstanceContextMode.Single)]
        public class ClienteManager : IClienteManager
        {
        
            [OperationBehavior(TransactionScopeRequired = true, 
            TransactionAutoComplete = true)]
             public void ModificarCliente(int id, <
             span class="kwrd">string nuevoNombre, string nuevoApellido)
              {
                    ...
              }
        }
        

        En el cliente:

        try
        {
            using (TransactionScope tx = new 
            TransactionScope(TransactionScopeOption.Required))
            {
                //código de la transacción
                tx.Complete();
            }
        }
        catch(Exception e)
        {
            Console.WriteLine("ERROR: {0}", e.Message);
        }

        Modo de transmisión

         Buffer vs Stream: si los mensajes se envían utilizando buffer (patrón duplex) el receptor los aloja en un buffer en memoria hasta que se complete la transmisión y no es posible acceder a los datos hasta que el mensaje sea recibido completamente. En cambio si utilizamos un stream (request-reply) los headers se colocan en un buffer y el body se expone como stream para que pueda ser accedido en partes pequeñas mientras aún se está transmitiendo. Se puede utilizar stream como parámetro o devolverlo como resultado y es ideal para la transmisión de mensajes grandes. Por defecto http, tcp/ip y named pipes utilizan buffer. Este modo de trasferencia se especifica al crear el objeto binding de nuestro endpoint.

         

        Ejemplo:

        TcpTransportBindingElement transporte = new TcpTransportBindingElement();
        transporte.TransferMode = TransferMode.Streamed;
        BinaryMessageEncodingBindingElement codificador = new 
        BinaryMessageEncodingBindingElement();
        CustomBinding binding = new CustomBinding(codificador, transporte);
        

        Ejemplo por archivo de configuración:

        <customBinding>
           <binding name="streamBinding">
              <binaryMessageEncoding />
              <tcpTransport transferMode=”Streamed/>
           </binding>
        </customBinding>
        

        Restricciones derivadas de utilizar transferencias del tipo Stream:

        • En el contrato el parámetro o resultado stream debe ser un subtipo de Sytem.IO.Stream o implementar IXmlSerializable.
        • Mensajes confiables, transacciones y la seguridad a nivel de mensaje SOAP dependen de una transmisión tipo buffer.
        • Los Encabezados (headers) SOAP siempre utilizan buffer y no deben superar la propiedad MaxBufferSize.

        El ejemplo que mostramos a continuación es una implementación de streaming que permite escuchar música desde un cliente. La música es publicada por un servicio de WCF.

        Ejemplo del Servicio:

        [ServiceContract(Namespace = "Test", SessionMode = SessionMode.Allowed)]
        public interface IStream
        {
            [OperationContract()]
                Stream Escuchar(string archivo);
                [OperationContract()]
                List<string> DameTemas();
        }
        
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
        public class StreamMusica : IStream
        {
                [OperationBehavior()]
                public Stream Escuchar(string archivo)
                {
                string mainPath = @".\Temas\";
                    mainPath += archivo;
                    FileStream fs = new FileStream(mainPath, 
                    FileMode.Open, FileAccess.Read);
                    return fs;
                }
        
                [OperationBehavior()]
                public List<string>  DameTemas()
                {
                string mainPath = @".\Temas\";
                    List<string> temas = new List<string>();
        
                   foreach (string archivo in Directory.GetFiles(mainPath,"*.wav"))
                   {
                       string nombre = Path.GetFileName(archivo);
                            temas.Add(nombre);
                }
        
                    return temas;
                }
        }

        App.Config:

        <?xml version="1.0" encoding="utf-8"?>
        <configuration>
         
            <system.serviceModel>
                <behaviors>
                    <serviceBehaviors>
                        <behavior name="NewBehavior">
                            <serviceMetadata httpGetEnabled="true" />
                        </behavior>
                    </serviceBehaviors>
                </behaviors>
                <bindings>
                    <basicHttpBinding>
                        <binding name="NewBinding0" maxBufferSize="65536" 
                        maxReceivedMessageSize="65536"
                            messageEncoding="Mtom" transferMode="Streamed" />
                    </basicHttpBinding>
                </bindings>
                <services>
                    <service behaviorConfiguration="NewBehavior" 
                    name="StreamService.StreamMusica">
                        <endpoint address="Stream" binding="basicHttpBinding" 
                        bindingConfiguration="NewBinding0"
                            name="ServiceEndpoint" contract="StreamService.IStream" />
                        <host>
                            <baseAddresses>
                                <add baseAddress="http://master3:8888/" />
                            </baseAddresses>
                        </host>
                    </service>
                </services>
            </system.serviceModel>
        </configuration>
        

         

        Ejemplo del Cliente:

         private void PLAYBUTTON_Click(object sender, EventArgs e)
        {
                #region Validar
                if (!ValidarArchivo())
                {
                    MsgHelper.ShowError("Debe seleccionar un archivo.");
                    return;
                }
                #endregion Validar
        
                try
                {
                    proxy = new StreamClient();
                    Player.Stream = proxy.Escuchar(bs.Current.ToString());
                    proxy.Close();
        
                    PLAYBUTTON.Enabled = false;
                    STOPBUTTON.Enabled = true;
        
                    Player.Play();
                }
                catch (Exception x)
                {
                    MsgHelper.ShowError(x.Message);
                }
        }
        

        Glosario

        WCF = Windows Communication Foundation.

        MSMQ = Microsoft Message Queuing.

        OS = Orientación a Servicios.

        OO = Orientación a Objetos.

        MTOM = Message Transmission Optimization Mechanism de SOAP.

        WSDL = Web Service Description Language.

        XSD = XML Schema Definition.

        SOAP = Simple Object Access Protocol.

        X.509 = Standard de certificados para firmar documentos y garantizar la seguridad en las comunicaciones.


        SDK: Software Development Kit (SDK).

         

        Referencias

         

        Programming Indigo, David Pallman, 2005.

        MSDN, Windows Communication Foundation, http://msdn2.microsoft.com/en-us/library/ms735119.aspx

        MSDN Magazine, Learn The ABCs Of Programming Windows Communication Foundation, http://msdn.microsoft.com/msdnmag/issues/06/02/WindowsCommunicationFoundation/

         

         

        Tags:

        WCF

        Introducción a WCF - Parte 4

        por Maxi Guillén - Daniel Laco  9. febrero 2007

        Introducción a Windows Communication Foundation PARTE 4

          Aproximación al desarrollo de servicios con WCF

         Si bien esta nota no es un tutorial, en esta parte mostraremos las diferentes partes que se pueden dar durante la programación de un servicio.

        Hay tres formas de encarar un proyecto de WCF

        • Por Código: implica crear primero el código de implementación del servicio, luego la definición del contrato y finalmente la descripción del servicio, ésta última se brinda mediante un MEX Endpoint (MetadataExchange) o archivos WSDL y XSD; no todos los tipos de clases pueden ser convertidos a un esquema XSD siendo esta su desventaja.
        • Por Contrato: implica crear primero la definición del contrato, luego la descripción del servicio. La descripción del servicio permite implementar el cliente generando código a partir de los metadatos. Finalmente se crea el Código de implementación. Esta es una aproximación ideal.
        • Sin contrato: no se considera el contrato y es ideal para trabajar a nivel de mensajes. Se deben crear los mensajes a enviar e interpretar los recibidos, se puede utilizar esta técnica si el servicio debe aceptar cualquier tipo de mensaje como por ejemplo un servicio de ruteo.

        Para las alternativas anteriores nos podemos apoyar en las facilidades de generación de código ya sea para un cliente, metadatos, etc. Esto se puede realizar a través de la herramienta SvcUtil que está disponible con el SDK, se encuentra por defecto en el path “C:\Archivos de programa\Microsoft SDKs\Windows\v6.0\Bin\” y o Visual Studio y nos permite entre otras cosas:

        1. Generación del código del cliente a partir de un servicio en ejecución o documentos de metadatos online
          • svcutil http://service/metadataEndpoint
        2. Generar tipos de Data Contracts a partir de un servicio en ejecución o documentos de metadatos online
          • svcutil /dconly http://service/metadataEndpoint
        3. Generar código en diferentes lenguajes
          • svcutil *.wsdl *.xsd /language:C#
          • svcutil /dconly *.xsd /language:VB
        4. Descargar documentos de metadatos desde un servicio en ejecución
          • svcutil /t:metadata http://service/metadataEndpoint
        5. Generar metadatos
          • svcutil myAssembly.dll
          • svcutil myServiceHost.exe /serviceName:myServiceName
        6. Mediante Visual Studio
          • Agregando una referencia a un servicio de WCF genera el Proxy para ser utilizado por el cliente.

        El desarrollo de un servicio puede ser realizado definiendo por código todas sus particularidades mediante atributos, por un archivo de configuración o una combinación de ambos. En los siguientes ejemplos mostramos las alternativas:

                 Ejemplos por Código

         [ServiceContract]
        public interface IReservacion
        {

            [OperationContract]
            iniciar(string nombre);
        }

         

         ...
        Uri direccion = new Uri("http://localhost:8080/CalculadoraService/");
        serviceHost = new ServiceHost();
        serviceHost.AddEndpoint( typeof(IMyContract), new WSProfileBinding(),direccion);
        ...

                    Ejemplos por Configuración

            Especifica varias de las características de un servicio a través de un archivo de configuración (address, binding, seguridad, comportambiento, etc). Disponemos para esto de la herramienta Service Configuration Editor referido anteriormente para asistirnos en la creación del archivo.

        <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
            <system.serviceModel>
                <services>
                    <service serviceType="MiServicio">
                        <endpoint
                            address=http://localhost:8000/ MiServicio / 
                            bindingSectionName="basicProfileBinding"
                            contractType="IMiContrato" />
                    service>
                services> 
            system.serviceModel>
        configuration>

        Pasos para crear un servicio con WCF

        1. Crear una definición una interfaz .NET (Contrato del servicio)
          [ServiceContract()]
              public interface ICalculadora
              {
                  [OperationContract()]
                  double Suma(double o1, double o2);
                  
                  [OperationContract]
                  double Resta(double o1, double o2);
                  
                  [OperationContract]
                  double Multiplicacion(double o1, double o2);
                  
                  [OperationContract]
                  double Division(double o1, double o2);
              }
        2. Implementar el Contrato y Comportamiento del servicio en una clase .NET (Tipo de Servicio)
          [ServiceBehavior()]
          public class Calculadora : ICalculadora
          {
              [OperationBehavior()]
              public double Suma(double o1, double o2)
              {
                  Console.WriteLine("Ejecutando Suma");
                  return o1 + o2;
              }
              
              [OperationBehavior]
              public double Resta(double o1, double o2)
              {
                  Console.WriteLine("Ejecutando Resta");
                  return o1 - o2;
              }
              
              [OperationBehavior]
              public double Multiplicacion(double o1, double o2)
              {
                  Console.WriteLine("Ejecutando Multiplicacion");
                  return o1 * o2;
              }
              
              [OperationBehavior]
              public double Division(double o1, double o2)
              {
                  Console.WriteLine("Ejecutando Division");
                  return o1 / o2;
              }
          }
        3. Programar el inicio del servicio
          public class CalculadoraManager
          {
              private static ServiceHost _serviceHost = null;
           
                  public static void StartService()
              {
                  Uri direccion = new Uri("http://localhost:8080/CalculadoraService/");
                  _serviceHost = new ServiceHost(
          typeof(CalculadoraService.Calculadora), direccion);
              }
          
              public static void StopService()
              {
                 if (_serviceHost.State != CommunicationState.Closed)
           {
                     _serviceHost.Close();
                     _serviceHost = null;
                 }
              }
          }
        4. Configurar característicasdel servicio en App.Config
          xml version="1.0" encoding="utf-8"?>
          <configuration>
            <system.serviceModel>
              <bindings>
                <basicHttpBinding>
                  <binding name="NewBinding0" />
                basicHttpBinding>
                <mexHttpBinding>
                  <binding name="NewBinding1" />
                mexHttpBinding>
              bindings>
              <behaviors>
                <serviceBehaviors>
                  <behavior name="NewBehavior">
                    <serviceMetadata httpGetEnabled="true" />
                  behavior>
                serviceBehaviors>
              behaviors>
              <services>
                <service name="CalculadoraService.Calculadora">
                  <endpoint address="http://localhost:8888/"
                  binding="basicHttpBinding"
                    bindingConfiguration="NewBinding0" 
                    contract="CalculadoraService.ICalculadora"/>
                  <endpoint binding="mexHttpBinding" 
                  bindingConfiguration="NewBinding1"
                      contract="IMetadataExchange" />
                service>
              services>
            system.serviceModel>
          configuration>
        5. Alojar el servicio utilizando la infraestructura WCF.
          1. Mediante un servicio de Windows
          2. En IIS
          3. Aplicación
          4. Otras

         

            Definición de Endpoint utilizando completamente la API de WCF.

         

            Definición de contrato por código mediante atributos:

        Tags:

        WCF

        Introducción a WCF - Parte 3

        por Maxi Guillén - Daniel Laco  9. febrero 2007

        Introducción a Windows Communication Foundation

        PARTE 3

         

        Comportamiento de los servicios en tiempo de ejecución

        (Service Behavior) 

        Representa las distintas características de ejecución del  servicio y se especifica como parámetros del contrato, en archivos de configuración o mediante la codificación. Permite manejo de errores, diferentes formas de instanciación  y manejo de concurrencia entre otras particularidades. 

        • Instanciación: determina como se instancian las clases que implementan un contrato.

        o        Singleton: una instancia atiende a todos los clientes.

        o        Por llamada: se crea una instancia de clase por cada mensaje de petición y luego se destruye.

        o        Sesión privada: se crea una instancia de clase por cada solicitud de un cliente.

        o        Sesión compartida: idem anterior pero los clientes pueden compartir una instancia. 

        • Concurrencia: como se relacionan las instancias con los Threads.

        o        Simple: especifica que el código del objeto servicio no puede ser ejecuto por más de un thread al mismo tiempo.

        o        Múltiple: especifica que el código del objeto servicio puede ser ejecutado por múltiples threads al mismo tiempo por lo que se deben establecer mecanismos de exclusión mutua.

        o        Reentrante:

        • Throlling: define condiciones de performance del servicio.  
        • Manejo de Errores: los errores pueden ser procesados por el programador o por el framework. También se puede reportar errores al cliente.  
        • Metadata: establece la publicación de los metadatos que brindan la descripción del servicio.  
        • Tiempo de vida: un servicio puede controlar el tiempo de vida de las sesiones de un cliente, especificando las operaciones de inicio y fin de sesión.  
        • Seguridad: establece la confidencialidad e integridad de los mensajes, autenticación, autorización, auditoría y detección de reintentos.  
        • Transacciones: el programador especifica si un servicio aceptará transacciones y el cliente controla el alcance y el tiempo de vida de una transacción.  

        Descripción del servicio 

        Un servicio puede informar al entorno sus capacidades y los requerimientos necesarios para poder interactuar con él y utiliza las siguientes especificaciones: 

        • Web Services Description Language (WSDL): formato que describe lo que puede hacer el servicio, como accederlo y donde se ubica.  
        • XML Schema (XSD): formato que describe estructuras complejas  que se pasan en los mensajes.  
        • WS-Policy: formato usado para describir las políticas del servicio. (Seguridad, Sesión, Disponibilidad)  
        • WS-MetaDataExchange (o WS-MEX): protocolo de acceso para solicitar la descripción del servicio.  

        Otras características 

        En esta parte enumeramos rápidamente algunos otros puntos de interés como ser Seguridad, Administración ,etc. 

        Lo estándares de Web Service soportados son: 

        • XML, XSD, XPath, SOAP, WSDL.  
        • WS-* architecture: WS-Addressing, WS-Policy, WS-Security, WS-Trust, WS-SecureConversation, WS-ReliableMessaging, WS-AtomicTransaction, WS-Coordination, WS-Policy, and MTOM. 

        Seguridad:

         

        • Autenticación disponible:  

        o        Usuario anónimo 

        o        Credenciales 

        o        Certificados (X.509 certificates) 

        o        Windows (Kerberos and NTLM) 

        o        User/Pass personalizados

         

        · Confidencialidad de los mensajes: 

        o        SSL 

        Administración y diagnóstico de servicios: 

        • End-to-end tracing: crea un registro de las actividades de los programas de WCF.  
        • Messaging logging: registra los mensajes enviados y recibidos.  
        • SvcTraceViewer: es una herramienta que incorpora el SDK 3.0 que permite revisar el End-to-end tracing y el Message logging.  
        • Windows Management Instrumentation: permite monitorear y controlar los programas de WCF en tiempo de ejecución.  
        • Windows Performance Counters: permite obtener estadísticas del comportamiento de los programas de WCF.  
        • SvcConfigEditor: es una herramienta que brinda una interfaz gráfica para editar archivos de configuración.

         

         

        Service Configuration Editor

         

         

         

        Tags:

        WCF

        Introducción a WCF - Parte 2

        por Maxi Guillén - Daniel Laco  9. febrero 2007

         Introducción a Windows Communication Foundation PARTE 2

        Algunos Conceptos de WCF

        Servicio: es un programa que expone sus capacidades a través de una colección de Endpoints y su descripción.

        Descripciones del servicio: se publican utilizando WSDL, XSD, WS-Policy y WS-MetaDataExchange.

        Cliente: es un programa que intercambia mensajes con uno o más Endpoints y también puede exponer sus propios Endpoints. Un cliente debe conocer la Dirección, el Contrato y el Binding de un servicio para poder comunicarse con el.

        Mensaje: representa unidad de intercambio de datos entre un Cliente y un Servicio.

         

        Podemos encontrar los siguientes patrones:

        • Simplex: mensajes de una sola vía donde no se espera respuesta alguna.
        • Duplex: mensajes de dos vías de modo asíncrono.
        • Request-Reply: mensajes de dos vías de modo síncrono, es decir se envía el mensaje y se aguarda por la respuesta.

         

         

         

        Patrones de mensajes

         

        Intermediario: la comunicación entre un cliente y un servicio puede pasar a través de otro programa, denominado servicio intermediario, que debería ser desconocido para el cliente. Este servicio no consume mensajes y es simplemente un punto por el que atraviesan los mensajes en su viaje desde el cliente hasta el servicio de destino. Las Tareas útiles que pueden realizar son:

         

        • Gateway: para hacer de puente entre redes.
        • Ruteo: permite dirigir un mensaje a uno de varios servicios de destino.
        • Firewall: puede prevenir que ciertos mensajes lleguen a un servicio.
        • Monitoreo de actividad.

         

        Ejemplo de intermediario

         

        La Estructura de un Servicio

         

        Un servicio se accede a travéz de un Endpoint (Punto de Conexión) que es el medio a través del cual interactúa con su entorno. Esá¡ formado por una dirección, un enlace y un contrato, lo que se llama habitualmente el ABC (Address, Binding, Contract) del servicio.

        • Address: es la dirección de red del Endpoint. (URI: http://localhost:8080/CalculadoraService/)

        o URI (Unifrom Resource Identifier): es una forma de especificar una la dirección de un recurso, esá¡ formada por un protocolo (Http, net.TCP, net.Pipe, net.msmq) seguido del nombre del host, puerto y path: Protoclo://Host [:Puerto][/path/[.../]]

        • Binding: especifica como un servicio se comunica con el entorno. Permite crear un stack de características para el canal de comunicaciones acorde a los requerimientos del servicio (El canal no se abre hasta que el servicio reciba el primer mensaje). Permite definir:

        o El medio de transporte (HTTP, TCP, MSMQ, etc)

        o La codificación de los datos (texto, MTOM, binario)

        o La seguridad requerida (HTTP, SOAP, Windows NTLM/Kerberos, user/pass, etc)

        o La confiabilidad de las comunicaciones (sesión)

        o El patrón de mensajes (Simplex, Duplex o Request-Reply)

        o La interoperabilidad deseada (Basic WS 1° generacion, WS-*, .Net, MSMQ)

         

         

        Características de un canal de comunicaciones

        • Contract: es una colección de operaciones, especifica lo que el Endpoint puede comunicar al entorno. Los tipos de contratos que podemos especificar son:

        o Service Contract: es una interfaz que implementa un servicio (Se publica utilizando WSDL). El Operation Contract son los métodos que forman parte de la interfaz, y que podrán ser accedidos por los clientes del servicio.

        o Data Contract: define las clases y estructuras complejas que puede retornar o recibir un servicio. Es implícito si el tipo de dato es serializable, es decir el tipo de dato se puede pasar directamente sin declararlo en el contrato. Es explícito en caso contrario y se debe especificar en un data contract (Serializacion/descerializacion) (Se publica utilizando un XML Schema). El Member Contract son los atributos o propiedades del objeto que forma parte de un data contract y podrán ser serializados.

        o Message Contract: especifica la estructura, cabecera y cuerpo, del mensaje SOAP. (Message Header y MessageBody). Nos permite definir si un atributo de una clase va viaja en la cabecera o en el cuerpo de un mensaje.

        Los tipos de bindings disponibles:

         

        Binding

        Intero-perabilidad

        Seguridad

        (Default)

        Sesión

        Transacción

        (Default)

        Duplex

        Codificación

        BasicHttpBinding

        Basic Profile 1.1

        (Ninguno),

        Transporte,

        Mensaje, Mixto

        No

        No

        n/a

        Texto, (MTOM)

        WSHttpBinding

        WS

        Transporte,

        (Mensaje),

        Mixto

        Si

        (No)

        Si

        n/a

        Texto, (MTOM)

        WSDualHttpBinding

        WS

        (Mensaje),

        Ninguno

        Si

        (No)

        Si

        Si

        Texto, (MTOM)

        WSFederationHttpBinding

        WS - Federation

        (Mensaje),

        Mixto,

        Ninguno

         

        (No)

        Si

        No

        Texto, (MTOM)

        NetTcpBinding

        .Net

        (Transporte),

        Mensaje,

        Ninguno,Mixto

        SI

        (No)

        Si

        Si

        Binaria

        NetNamedPipeBinding

        .Net

        (Transporte),

        Mensaje,

        Ninguno,Ambos

        Si

        (No)

        Si

        Si

        Binaria

        NetMsmqBinding

        .Net

        Ninguno,(Transporte)

        No

        (No)

        Si

        No

        -

        NetPeerTcpBinding

        Peer

        Mensaje,

        (Transporte),

        Ambos

        No

        (No)

        Si

        -

        MsmqIntegrationBinding

        MSMQ

        (Transporte)

        No

        (No)

        Si

        n/a

        -

        Tags:

        WCF

        Introducción a WCF - Parte 1

        por Maxi Guillén - Daniel Laco  9. febrero 2007

        Introducción a Windows Communication Foundation

        PARTE 1

         

         
        En esta nota presentaremos someramente las características principales de Windows Communication Foundation (WCF). Es nuestro interés dar un panorama general de las posibilidades que brinda, ver algunos ejemplos y mostrar algunos puntos a modo enumerativo.
         
        WCF es un modelo de programación unificado para la creación y puesta en marcha de sistemas distribuidos orientados a una arquitectura de servicios.
         
        Integra todas las tecnologías para el desarrollo de aplicaciones distribuidas existentes hasta la fecha: MSMQ, Web Services, .Net Remoting, Enterprise services y Web Services Enhacements (WSE).
         
         
        Brinda:
        • Web Services Seguros
        • Aplicaciones distribuidas transaccionables y confiables
        • Interoperabilidad basada en Web Services (WS-*)
        • Variedad de transportes
        • Varias posibilidades para alojar nuestros servicios (en IIS, en una Aplicación de WinForms, etc.)
        • Conjunto de clases accesibles a través del namespace System.ServiceModel para desarrollar nuestros servicios. 
        Abarca:
        • Transporte
        • Sistemas de seguridad
        • Patrones de mensajería
        • Sistemas de representación de datos
        • Modelos de alojamiento 
        Está disponible en Windows Vista / XP / Server 2003 / Windows "Longhorn" Server y forma parte de lo que se llama .NET 3.0
         
        Orientación a servicios vs Orientación a Objetos
         
        Podríamos decir que una aplicación distribuida orientada a objetos es un conjunto de componentes con fuerte acoplamiento ya que se construye a partir de bibliotecas de clases, las cuales tienen dependencias e interactúan llamando a objetos distribuidos. Para esto deben compartir un sistema de tipos de datos común. No sería la mejor manera de construir una aplicación distribuida.
         
        La orientación a servicios es un complemento de la orientación a objetos donde las comunicaciones serán el centro de la arquitectura. Un sistema distribuido orientado a servicios es un conjunto de componentes débilmente acoplados que brindan servicios comunicándose por medio de mensajes. 
         
        Los pilares de la Orientación a Servicios (OS) son: 
        1. Los límites son explícitos: los sistemas distribuidos orientados a servicios interactúan enviando mensajes a través de límites formales y explícitos, no debemos considerar que hay detrás (la implementación) ya que esto es justamente lo que preserva la flexibilidad. Cruzar éstos límites tiene un costo en tiempo de procesamiento y en las comunicaciones. Por esto las llamadas a servicios deben ser simples y eficientes. Cada interacción implica un cruce de límites. 
        1. Los servicios son autónomos: los servicios se despliegan, administran y versionan en forma independiente. Los servicios no deberían fallar si cualquier servicio dependiente no está disponible. No existe una entidad controladora de servicios. Deben tener contemplado el manejo de los errores, ya sean internos propios del servicio, o errores generados por los clientes por mal formación de los mensajes, etc. 
        1. Los servicios comparten Esquemas y Contratos, no clases y tipos: los servicios utilizan contratos para pasar datos y especificar comportamientos, no pasan clases o tipos. Los servicios no tienen ningún conocimiento del entorno de ejecución del cliente u otro servicio,  ya que la información que se intercambia es independiente de la plataforma. 
        1. Compatibilidad basada en políticas: cada servicio brinda una política, descripción de si mismo, de sus capacidades y requerimientos. Esto permite que dos sistemas encuentren un área común para poder interactuar. Las políticas separan las interacciones que puede tener de las restricciones. 
         
        Algunos de los beneficios más importantes de los servicios: 
        1. Aislamiento: la modificación del comportamiento de un servicio no implica modificar o recompilar otros servicios o clientes. 
        1. Independencia de ubicación: es transparente si un servicio se ejecuta localmente o en un equipo remoto, la forma de utilización es la misma. 
        1. Flexibilidad de transporte: en cuanto a protocolo y formato de representación, ya que existen varias alternativas o incluso pueden crearse en forma personalizada. 
        1. Independencia de la plataforma e implementación: no necesitamos conocer el contexto de ejecución del servicio para poder interactuar con el. 
        1. Independencia del tiempo: un servicio no necesita estar en línea para poder interactuar con el. Por ejemplo si utilizamos MSMQ. 
         
        Arquitectura y componentes de una aplicación WCF
         
        Ahora veamos la arquitectura, las capas que componen una aplicación con WCF y algunos de los puntos más sobresalientes de cada una.
         
        1. Capa de Contratos: define los puntos en común que tienen que tener los servicios y clientes para poder interactuar.
          1. Data Contract: define los objetos y estructuras complejas comunes.
          2. Message Contract: define cual información viaja en la cabecera y cual en el cuerpo de los mensajes.
          3. Service Contract: define el comportamiento que el servicio expondrá al entorno.
          4. Policy y Binding: define las características del canal de comunicaciones y requisitos que hay que cumplir para poder interactuar con el servicio. 
        1. Capa de ejecución del servicio: esta capa describe el comportamiento del servicio cuando está operando. Opera principalmente sobre el cuerpo de un mensaje recibido.
          1. Throlling behavior: define la cantidad de mensajes que podrá procesar el servicio.
          2. Error behavior: define que hacer en caso de error y como se lo informa al cliente.
          3. Metadata behavior: define como el servicio publicará una descripción de si mismo.
          4. Instante behavior: define la forma en que se instanciará el servicio propiamente dicho, es decir la clase que implementa un contrato.
          5. Transaction behavior: define las operaciones que podrán formar parte de transacciones y realizar un rollback en caso de error.
          6. Dispatch: controla como WCF procesará un mensaje.
          7. Message inspection: permite inspeccionar las distintas partes de un mensaje.
          8. Parameter filtering: permite que ocurra una acción predefinida según el contenido de la cabecera de los mensajes. 
        1. Capa de Mensajería: esta capa esta formada por canales de comunicaciones y opera sobre la cabecera y el cuerpo del mensaje. Permite formar un stack con características de un canal de comunicaciones acorde a los requerimientos de nuestro sistema.
          1. WS-Security Channel: implementación de la especificación de WS que permite seguridad a nivel de mensaje.
          2. WS-Reliable Messaging Channel: implementación de la especificación de WS que permite asegurar la entrega de mensajes.
          3. Encoders: define el conjunto de formatos de representación de datos que podemos utilizar.
          4. Http Channel: define que el transporte de mensajes se realizará a través del protocolo Http.
          5. TCP Channel: define que el transporte de mensajes se realizará utilizando el protocolo Tcp.
          6. Transaction Flow Channel: define el patrón de los mensajes para posibilitar transacciones.
          7. NamedPipe Channel: posibilita la comunicación entre procesos a través de tuberías.
          8. MSMQ Channel: posibilita la interacción con un servicio a través de una cola de mensajes. 
        1. Hosting y Activación: esta capa define las posibles formas de ejecutar y activar un servicio
          1. Self-Hosted: a través de un archivo ejecutable (.exe)
          2. Administrado: a través de un agente externo (Internet Información Service o Windows Activation Service).
          3. Servicio de Windows
          4. Los componentes COM+ pueden ser alojados como un servicio WCF

         

         

        Tags:

        WCF

        Acerca de los Autores

        Este es el blog del equipo de VEMN SA 
        Presentaremos temas que nos parezcan de interés sobre tecnología .NET, Procesos y Metodologías y todo aquello relacionado con el proceso de desarrollo de Software

        Month List

        BlogRoll

        Download OPML file OPML