Tutorial: Exposición de un servicio WCF REST local a un cliente externo mediante el uso de Azure WCF RelayTutorial: Expose an on-premises WCF REST service to external client by using Azure WCF Relay

En este tutorial se describe cómo crear un servicio y una aplicación cliente de WCF Relay mediante Azure Relay.This tutorial describes how to build a WCF Relay client application and service using Azure Relay. Para ver un tutorial parecido donde se usa Mensajería de Service Bus, consulte Introducción a las colas de Service Bus.For a similar tutorial that uses Service Bus messaging, see Get started with Service Bus queues.

El trabajo con este tutorial le proporciona unos conocimientos sobre los pasos para crear una aplicación cliente y de servicio de WCF Relay.Working through this tutorial gives you an understanding of the steps to create a WCF Relay client and service application. Como sus homólogos WCF originales, un servicio es una construcción que expone uno o varios puntos de conexión.Like their original WCF counterparts, a service is a construct that exposes one or more endpoints. Cada uno de ellos expone una o varias operaciones de servicio.Each endpoint exposes one or more service operations. El extremo de un servicio especifica una dirección donde se puede encontrar el servicio, un enlace que contiene la información que un cliente debe comunicar al servicio y un contrato que define la funcionalidad que ofrece el servicio a sus clientes.The endpoint of a service specifies an address where the service can be found, a binding that contains the information that a client must communicate with the service, and a contract that defines the functionality provided by the service to its clients. La diferencia principal entre WCF y WCF Relay es que el punto de conexión se expone en la nube en lugar de localmente en su equipo.The main difference between WCF and WCF Relay is that the endpoint is exposed in the cloud instead of locally on your computer.

Una vez que complete la secuencia de secciones de este tutorial, dispondrá de un servicio en ejecución.After you work through the sequence of sections in this tutorial, you'll have a running service. También tendrá un cliente que puede invocar las operaciones del servicio.You'll also have a client that can invoke the operations of the service.

En este tutorial, hará lo siguiente:You do the following tasks in this tutorial:

  • Instalar los requisitos previos del tutorial.Install prerequisites for this tutorial.
  • Creación de un espacio de nombres de RelayCreate a Relay namespace.
  • Crear un contrato de servicio WCF.Create a WCF service contract.
  • Implementar el contrato de WCF.Implement the WCF contract.
  • Hospedar y ejecutar un servicio WCF para registrarse con el servicio Relay.Host and run the WCF service to register with the Relay service.
  • Crear un cliente WCF para el contrato de servicio.Create a WCF client for the service contract.
  • Configurar el cliente de WCF.Configure the WCF client.
  • Implementar el cliente de WCF.Implement the WCF client.
  • Ejecución de las aplicacionesRun the applications.

PrerrequisitosPrerequisites

Para completar este tutorial, debe cumplir los siguientes requisitos previos:To complete this tutorial, you need the following prerequisites:

Creación de un espacio de nombres de RelayCreate a Relay namespace

El primer paso consiste en crear un espacio de nombres y obtener una clave de firma de acceso compartido (SAS).The first step is to create a namespace, and to obtain a Shared Access Signature (SAS) key. Un espacio de nombres proporciona un límite de aplicación para cada aplicación que se expone a través del servicio de retransmisión.A namespace provides an application boundary for each application exposed through the relay service. El sistema genera una clave SAS automáticamente cuando se crea un espacio de nombres de servicio.An SAS key is automatically generated by the system when a service namespace is created. La combinación del espacio de nombres de servicio y la clave SAS proporciona las credenciales para que Azure autentique el acceso a una aplicación.The combination of service namespace and SAS key provides the credentials for Azure to authenticate access to an application.

  1. Inicie sesión en Azure Portal.Sign in to the Azure portal.

  2. Seleccione Crear un recurso.Select Create a resource. Seleccione Integración > Retransmisión.Then, select Integration > Relay. Si no ve Retransmisión en la lista, seleccione Ver todo en la esquina superior derecha.If you don't see Relay in the list, select See All in the top-right corner.

  3. Seleccione Crear y escriba un nombre de espacio de nombres en el campo Nombre.Select Create, and enter a namespace name in the Name field. Azure Portal comprueba si el nombre está disponible.Azure portal checks to see if the name is available.

  4. Elija la suscripción de Azure en la que se va a crear el espacio de nombres.Choose an Azure subscription in which to create the namespace.

  5. En Grupo de recursos, elija un grupo de recursos existente en el que se colocará el espacio de nombres o cree uno.For Resource group, choose an existing resource group in which to place the namespace, or create a new one.

  6. Seleccione el país o región donde se debe hospedar el espacio de nombres.Select the country or region in which your namespace should be hosted.

    Crear un espacio de nombres

  7. Seleccione Crear.Select Create. Azure Portal crea ahora el espacio de nombres del servicio y lo habilita.The Azure portal creates your namespace and enables it. Tras unos minutos, el sistema realiza el aprovisionamiento de los recursos para la cuenta.After a few minutes, the system provisions resources for your account.

Obtención de las credenciales de administraciónGet management credentials

  1. Seleccione Todos los recursos y, después, seleccione el nombre del espacio de nombres recién creado.Select All resources, and then choose the newly created namespace name.

  2. Seleccione Directivas de acceso compartido.Select Shared access policies.

  3. En Directivas de acceso compartido, seleccione RootManageSharedAccessKey.Under Shared access policies, select RootManageSharedAccessKey.

  4. En Directiva SAS: RootManageSharedAccessKey, haga clic en el botón Copiar situado junto a Cadena de conexión principal.Under SAS Policy: RootManageSharedAccessKey, select the Copy button next to Primary Connection String. Esta acción copia la cadena de conexión en el Portapapeles para su uso posterior.This action copies the connection string to your clipboard for later use. Pegue este valor en el Bloc de notas o cualquier otra ubicación temporal.Paste this value into Notepad or some other temporary location.

  5. Repita el paso anterior para copiar y pegar el valor de Clave principal en una ubicación temporal para su uso posterior.Repeat the preceding step to copy and paste the value of Primary key to a temporary location for later use.

    connection-string

Definición de un contrato de servicio de WCFDefine a WCF service contract

El contrato de servicio especifica qué operaciones admite este.The service contract specifies what operations the service supports. Las operaciones son métodos o funciones de servicio web.Operations are web service methods or functions. Los contratos se crean mediante la definición de una interfaz de C++, C# o Visual Basic.Contracts are created by defining a C++, C#, or Visual Basic interface. Cada método de la interfaz corresponde a una operación de servicio específica.Each method in the interface corresponds to a specific service operation. Todas las interfaces deben tener el atributo ServiceContractAttribute aplicado, y todas las operaciones deben tener el atributo OperationContractAttribute aplicado.Each interface must have the ServiceContractAttribute attribute applied to it, and each operation must have the OperationContractAttribute attribute applied to it. Si un método en una interfaz que tiene el atributo ServiceContractAttribute no tiene el atributo OperationContractAttribute, no se expone ese método.If a method in an interface that has the ServiceContractAttribute attribute doesn't have the OperationContractAttribute attribute, that method isn't exposed. El código para estas tareas se ofrece en el ejemplo a continuación del procedimiento.The code for these tasks is provided in the example following the procedure. Para leer una descripción completa de los contratos y servicios, consulte Diseño e implementación de servicios.For a larger discussion of contracts and services, see Designing and Implementing Services.

Creación de un contrato de retransmisión con una interfazCreate a relay contract with an interface

  1. Inicie Microsoft Visual Studio como administrador.Start Microsoft Visual Studio as an administrator. Para hacerlo, haga clic con el botón derecho en el icono del programa Visual Studio y, después, seleccione Ejecutar como administrador.To do so, right-click the Visual Studio program icon, and select Run as administrator.

  2. En Visual Studio, seleccione Crear un proyecto nuevo.In Visual Studio, select Create a new project.

  3. En Crear un proyecto, elija Aplicación de consola (.NET Framework) para C# y seleccione Siguiente.In Create a new project, choose Console App (.NET Framework) for C# and select Next.

  4. Asigne al proyecto el nombre EchoService y seleccione Crear.Name the project EchoService and select Create.

    Creación de una aplicación de consola

  5. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Administrar paquetes NuGet.In Solution Explorer, right-click the project and select Manage NuGet Packages. En el Administrador de paquetes NuGet, seleccione Examinar y, después, busque y elija WindowsAzure.ServiceBus.In the NuGet Package Manager, select Browse, then search for and choose WindowsAzure.ServiceBus. Seleccione Instalar y acepte las condiciones de uso.Select Install, and accept the terms of use.

    Paquete de Service Bus

    Este paquete agrega automáticamente referencias a las bibliotecas de Service Bus y a System.ServiceModel de WCF.This package automatically adds references to the Service Bus libraries and the WCF System.ServiceModel. System.ServiceModel es el espacio de nombres que permite el acceso mediante programación a las características básicas de WCF.System.ServiceModel is the namespace that enables you to programmatically access the basic features of WCF. Service Bus utiliza muchos de los objetos y atributos de WCF para definir contratos de servicio.Service Bus uses many of the objects and attributes of WCF to define service contracts.

  6. Agregue las siguientes instrucciones using al principio de Program.cs:Add the following using statements at the top of Program.cs:

    using System.ServiceModel;
    using Microsoft.ServiceBus;
    
  7. Cambie el nombre del espacio de nombres de su nombre predeterminado de EchoService a Microsoft.ServiceBus.Samples.Change the namespace name from its default name of EchoService to Microsoft.ServiceBus.Samples.

    Importante

    En este tutorial se usa el espacio de nombres de C# Microsoft.ServiceBus.Samples, que es el espacio de nombres del tipo administrado por contrato que se utiliza en el archivo de configuración en la sección Configurar el cliente de WCF.This tutorial uses the C# namespace Microsoft.ServiceBus.Samples which is the namespace of the contract-based managed type that is used in the configuration file in the Configure the WCF client section. Puede especificar cualquier espacio de nombres que desee al compilar este ejemplo.You can specify any namespace you want when you build this sample. No obstante, el tutorial no funcionará a menos que también modifique los espacios de nombres del contrato y el servicio de manera acorde, en el archivo de configuración de la aplicación.However, the tutorial will not work unless you then modify the namespaces of the contract and service accordingly, in the application configuration file. El espacio de nombres especificado en el archivo App.config debe ser el mismo que el que se especifique en los archivos de C#.The namespace specified in the App.config file must be the same as the namespace specified in your C# files.

  8. Inmediatamente después de la declaración del espacio de nombres Microsoft.ServiceBus.Samples, pero dentro del espacio de nombres, defina una nueva interfaz denominada IEchoContract y aplique el atributo ServiceContractAttribute a la interfaz con un valor de espacio de nombres de https://samples.microsoft.com/ServiceModel/Relay/.Directly after the Microsoft.ServiceBus.Samples namespace declaration, but within the namespace, define a new interface named IEchoContract and apply the ServiceContractAttribute attribute to the interface with a namespace value of https://samples.microsoft.com/ServiceModel/Relay/. Pegue el siguiente fragmento de código después de la declaración de espacios de nombres:Paste the following code after the namespace declaration:

    [ServiceContract(Name = "IEchoContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    public interface IEchoContract
    {
    }
    

    El valor del espacio de nombres difiere del espacio de nombres que utiliza en todo el ámbito de su código.The namespace value differs from the namespace that you use throughout the scope of your code. En su lugar, el valor del espacio de nombres se usa como identificador único para este contrato.Instead, the namespace value is used as a unique identifier for this contract. La especificación del espacio de nombres impide explícitamente que el valor del espacio de nombres predeterminado se agregue al nombre del contrato.Specifying the namespace explicitly prevents the default namespace value from being added to the contract name.

    Nota

    Normalmente, el espacio de nombres del contrato de servicio contiene un esquema de nomenclatura que incluye información de versión.Typically, the service contract namespace contains a naming scheme that includes version information. Al incluirse la información de versión en el espacio de nombres del contrato de servicio, los servicios pueden aislar los cambios más importantes mediante la definición de un nuevo contrato de servicio con un nuevo espacio de nombres y su exposición en un nuevo extremo.Including version information in the service contract namespace enables services to isolate major changes by defining a new service contract with a new namespace and exposing it on a new endpoint. De esta manera, los clientes pueden seguir usando el contrato de servicio anterior sin tener que actualizarse.In this manner, clients can continue to use the old service contract without having to be updated. La información de versión puede constar de una fecha o un número de compilación.Version information can consist of a date or a build number. Para obtener más información, vea Control de versiones del servicio.For more information, see Service Versioning. Para este tutorial, el esquema de nomenclatura del espacio de nombres del contrato de servicio no contiene información de versión.For this tutorial, the naming scheme of the service contract namespace does not contain version information.

  9. En la interfaz de IEchoContract, declare un método para la operación sencilla que el contrato IEchoContract expone en la interfaz y aplique el atributo OperationContractAttribute al método que quiere exponer como parte del contrato público de Relay WCF de la siguiente forma:Within the IEchoContract interface, declare a method for the single operation the IEchoContract contract exposes in the interface and apply the OperationContractAttribute attribute to the method that you want to expose as part of the public WCF Relay contract, as follows:

    [OperationContract]
    string Echo(string text);
    
  10. Justo después de la definición de interfaz IEchoContract, declare un canal que herede de IEchoContract y también de la interfaz de IClientChannel, como se muestra a continuación:Directly after the IEchoContract interface definition, declare a channel that inherits from both IEchoContract and also to the IClientChannel interface, as shown here:

    public interface IEchoChannel : IEchoContract, IClientChannel { }
    

    Un canal es el objeto de WCF a través del cual el host y el cliente se pasan información entre sí.A channel is the WCF object through which the host and client pass information to each other. Más tarde, escribirá código para el canal a fin de enviar información entre las dos aplicaciones.Later, you'll write code against the channel to echo information between the two applications.

  11. Seleccione Compilar > Compilar solución o seleccione Ctrl+Mayús+B para confirmar la precisión del trabajo realizado.Select Build > Build Solution or select Ctrl+Shift+B to confirm the accuracy of your work so far.

Ejemplo de un contrato de WCFExample of a WCF contract

En el ejemplo de código siguiente se muestra una interfaz básica que define un contrato de WCF Relay.The following code shows a basic interface that defines a WCF Relay contract.

using System;
using System.ServiceModel;

namespace Microsoft.ServiceBus.Samples
{
    [ServiceContract(Name = "IEchoContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    public interface IEchoContract
    {
        [OperationContract]
        String Echo(string text);
    }

    public interface IEchoChannel : IEchoContract, IClientChannel { }

    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

Ahora que la interfaz se ha creado, puede implementarla.Now that the interface is created, you can implement the interface.

Implementación del contrato de WCFImplement the WCF contract

La creación de una instancia de Azure Relay requiere que primero cree el contrato mediante una interfaz.Creating an Azure relay requires that you first create the contract by using an interface. Para más información sobre cómo crear la interfaz, consulte la sección anterior.For more information about creating the interface, see the previous section. El procedimiento siguiente implementa la interfaz.The next procedure implements the interface. Esta tarea conlleva la creación de una clase denominada EchoService que implementa la interfaz IEchoContract definida por el usuario.This task involves creating a class named EchoService that implements the user-defined IEchoContract interface. Después de implementar la interfaz, se debe configurar con un archivo App.config.After you implement the interface, you then configure the interface using an App.config configuration file. El archivo de configuración contiene la información necesaria para la aplicación.The configuration file contains necessary information for the application. Esta información incluye el nombre del servicio, el nombre del contrato y el tipo de protocolo que se utiliza para comunicarse con el servicio de retransmisión.This information includes the name of the service, the name of the contract, and the type of protocol that is used to communicate with the relay service. El código utilizado para estas tareas se proporciona en el ejemplo que sigue al procedimiento.The code used for these tasks is provided in the example that follows the procedure. Para obtener información más general sobre cómo implementar un contrato de servicio, consulte Implementación de contratos de servicio.For a more general discussion about how to implement a service contract, see Implementing Service Contracts.

  1. Cree una nueva clase denominada EchoService directamente después de la definición de la interfaz IEchoContract.Create a new class named EchoService directly after the definition of the IEchoContract interface. La clase EchoService implementa la interfaz IEchoContract.The EchoService class implements the IEchoContract interface.

    class EchoService : IEchoContract
    {
    }
    

    Al igual que otras implementaciones de interfaz, puede implementar la definición en un archivo diferente.Similar to other interface implementations, you can implement the definition in a different file. Sin embargo, para este tutorial, la implementación se ubica en el mismo archivo que la definición de la interfaz y el método Main().However, for this tutorial, the implementation is located in the same file as the interface definition and the Main() method.

  2. Aplique el atributo ServiceBehaviorAttribute en la interfaz de IEchoContract.Apply the ServiceBehaviorAttribute attribute to the IEchoContract interface. El atributo especifica el nombre del servicio y el espacio de nombres.The attribute specifies the service name and namespace. Después de hacerlo, aparecerá la clase EchoService de la siguiente manera:After doing so, the EchoService class appears as follows:

    [ServiceBehavior(Name = "EchoService", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    class EchoService : IEchoContract
    {
    }
    
  3. Implemente el método Echo definido en la interfaz IEchoContract de la clase EchoService.Implement the Echo method defined in the IEchoContract interface in the EchoService class.

    public string Echo(string text)
    {
        Console.WriteLine("Echoing: {0}", text);
        return text;
    }
    
  4. Seleccione Compilar > Compilar solución o seleccione Ctrl+Mayús+B.Select Build > Build Solution or select Ctrl+Shift+B.

Definición de la configuración del host de serviciosDefine the configuration for the service host

El archivo de configuración es similar a un archivo de configuración de WCF.The configuration file is similar to a WCF configuration file. Incluye el nombre del servicio, el punto de conexión y el enlace.It includes the service name, endpoint, and binding. El punto de conexión es la ubicación que Azure Relay expone para que los clientes y hosts se comuniquen entre sí.The endpoint is the location Azure Relay exposes for clients and hosts to communicate with each other. El enlace es el tipo de protocolo que se utiliza para la comunicación.The binding is the type of protocol that is used to communicate. La principal diferencia es que el punto de conexión de servicio configurado hace referencia a un enlace NetTcpRelayBinding que no forma parte de .NET Framework.The main difference is that this configured service endpoint refers to a NetTcpRelayBinding binding, which isn't part of the .NET Framework. NetTcpRelayBinding es uno de los enlaces que define el servicio.NetTcpRelayBinding is one of the bindings defined by the service.

  1. En el Explorador de soluciones, haga doble clic en App.config para abrir el archivo en el editor de Visual Studio.In Solution Explorer, double-click App.config to open the file in the Visual Studio editor.

  2. En el elemento <appSettings>, reemplace los marcadores de posición con el nombre de su espacio de nombres de servicio y la clave SAS que copió en el paso anterior.In the <appSettings> element, replace the placeholders with the name of your service namespace, and the SAS key that you copied in an earlier step.

  3. Dentro de las etiquetas <system.serviceModel>, agregue un elemento <services>.Within the <system.serviceModel> tags, add a <services> element. Puede definir varias aplicaciones de retransmisión en un único archivo de configuración.You can define multiple relay applications in a single configuration file. Sin embargo, este tutorial solo define una.However, this tutorial defines only one.

    <?xmlversion="1.0"encoding="utf-8"?>
    <configuration>
      <system.serviceModel>
        <services>
    
        </services>
      </system.serviceModel>
    </configuration>
    
  4. Dentro del elemento <services>, agregue un elemento <service> para definir el nombre del servicio.Within the <services> element, add a <service> element to define the name of the service.

    <service name="Microsoft.ServiceBus.Samples.EchoService">
    </service>
    
  5. Dentro del elemento <service>, defina la ubicación del contrato del punto de conexión y también el tipo de enlace del extremo.Within the <service> element, define the location of the endpoint contract, and also the type of binding for the endpoint.

    <endpoint contract="Microsoft.ServiceBus.Samples.IEchoContract" binding="netTcpRelayBinding"/>
    

    El extremo define dónde buscará el cliente la aplicación host.The endpoint defines where the client will look for the host application. Más adelante en el tutorial, se usa este paso para crear un identificador URI que expone completamente el host a través de Azure Relay.Later, the tutorial uses this step to create a URI that fully exposes the host through Azure Relay. El enlace declara que se está usando TCP como el protocolo para comunicarse con el servicio de retransmisión.The binding declares that we're using TCP as the protocol to communicate with the relay service.

  6. Seleccione Compilar > Compilar solución o seleccione Ctrl+Mayús+B para confirmar la precisión del trabajo realizado.Select Build > Build Solution or select Ctrl+Shift+B to confirm the accuracy of your work so far.

Ejemplo de implementación de un contrato de servicioExample of implementation of a service contract

En el código siguiente se muestra la implementación del contrato de servicio.The following code shows the implementation of the service contract.

[ServiceBehavior(Name = "EchoService", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]

    class EchoService : IEchoContract
    {
        public string Echo(string text)
        {
            Console.WriteLine("Echoing: {0}", text);
            return text;
        }
    }

En el código siguiente se muestra el formato básico del archivo App.config asociado al servicio.The following code shows the basic format of the App.config file associated with the service host.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Microsoft.ServiceBus.Samples.EchoService">
        <endpoint contract="Microsoft.ServiceBus.Samples.IEchoContract" binding="netTcpRelayBinding" />
      </service>
    </services>
    <extensions>
      <bindingExtensions>
        <add name="netTcpRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </bindingExtensions>
    </extensions>
  </system.serviceModel>
</configuration>

Hospedaje y ejecución de un servicio WCF para registrarse con el servicio RelayHost and run the WCF service to register with the relay service

Este paso describe cómo ejecutar un servicio de Azure Relay.This step describes how to run an Azure Relay service.

Creación de las credenciales de retransmisiónCreate the relay credentials

  1. En Main(), cree dos variables para almacenar el espacio de nombres y la clave de SAS que se leen desde la ventana de la consola.In Main(), create two variables in which to store the namespace and the SAS key that are read from the console window.

    Console.Write("Your Service Namespace: ");
    string serviceNamespace = Console.ReadLine();
    Console.Write("Your SAS key: ");
    string sasKey = Console.ReadLine();
    

    La clave de SAS se usará más adelante para obtener acceso al proyecto.The SAS key will be used later to access your project. El espacio de nombres se pasa como parámetro a CreateServiceUri para crear un URI de servicio.The namespace is passed as a parameter to CreateServiceUri to create a service URI.

  2. Con un objeto TransportClientEndpointBehavior, declare que usará una clave de SAS como tipo de credencial.Using a TransportClientEndpointBehavior object, declare that you'll be using an SAS key as the credential type. Agregue el código siguiente directamente después del código de que se agregó en el último paso.Add the following code directly after the code added in the last step.

    TransportClientEndpointBehavior sasCredential = new TransportClientEndpointBehavior();
    sasCredential.TokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider("RootManageSharedAccessKey", sasKey);
    

Creación de una dirección base para el servicioCreate a base address for the service

Siguiendo el código que agregó en la sección anterior, cree una instancia de Uri para la dirección base del servicio.After the code you added in the previous section, create a Uri instance for the base address of the service. Este identificador URI especifica el esquema de Service Bus, el espacio de nombres y la ruta de acceso de la interfaz del servicio.This URI specifies the Service Bus scheme, the namespace, and the path of the service interface.

Uri address = ServiceBusEnvironment.CreateServiceUri("sb", serviceNamespace, "EchoService");

El valor "SB" es una abreviatura del esquema de Service Bus.The value "sb" is an abbreviation for the Service Bus scheme. Indica que se está usando TCP como protocolo.It indicates that we're using TCP as the protocol. Este esquema también se indicó anteriormente en el archivo de configuración, cuando se especificó NetTcpRelayBinding como el enlace.This scheme was also previously indicated in the configuration file, when NetTcpRelayBinding was specified as the binding.

Para este tutorial, el identificador URI es sb://putServiceNamespaceHere.windows.net/EchoService.For this tutorial, the URI is sb://putServiceNamespaceHere.windows.net/EchoService.

Creación y configuración del host de serviciosCreate and configure the service host

  1. Cuando aún esté trabajando en Main(), establezca el modo de conectividad en AutoDetect.Still working in Main(), set the connectivity mode to AutoDetect.

    ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.AutoDetect;
    

    El modo de conectividad describe el protocolo que usa el servicio para comunicarse con el servicio de retransmisión; HTTP o TCP.The connectivity mode describes the protocol the service uses to communicate with the relay service; either HTTP or TCP. Con la configuración predeterminada AutoDetect, el servicio intenta conectarse a Azure Relay a través de TCP si está disponible, y HTTP si no lo está.Using the default setting AutoDetect, the service attempts to connect to Azure Relay over TCP if it's available, and HTTP if TCP isn't available. Este resultado difiere del protocolo que especifica el servicio para la comunicación del cliente.This result differs from the protocol the service specifies for client communication. Dicho protocolo viene determinado por el enlace utilizado.That protocol is determined by the binding used. Por ejemplo, un servicio puede usar el enlace BasicHttpRelayBinding, que especifica que su punto de conexión se comunica con los clientes a través de HTTP.For example, a service can use the BasicHttpRelayBinding binding, which specifies that its endpoint communicates with clients over HTTP. Ese mismo servicio podría especificar ConnectivityMode.AutoDetect para que el servicio se comunique con Azure Relay mediante TCP.That same service could specify ConnectivityMode.AutoDetect so that the service communicates with Azure Relay over TCP.

  2. Cree el host del servicio, con el identificador URI creado anteriormente en esta sección.Create the service host, using the URI created earlier in this section.

    ServiceHost host = new ServiceHost(typeof(EchoService), address);
    

    El host del servicio es el objeto de WCF que crea una instancia del servicio.The service host is the WCF object that instantiates the service. En este caso, se pasa el tipo de servicio que quiere crear (un tipo EchoService) y también la dirección en la que quiere exponer el servicio.Here, you pass it the type of service you want to create, an EchoService type, and also to the address at which you want to expose the service.

  3. En la parte superior del archivo Program.cs, agregue referencias a System.ServiceModel.Description y Microsoft.ServiceBus.Description.At the top of the Program.cs file, add references to System.ServiceModel.Description and Microsoft.ServiceBus.Description.

    using System.ServiceModel.Description;
    using Microsoft.ServiceBus.Description;
    
  4. De nuevo en Main(), configure el punto de conexión para permitir el acceso público.Back in Main(), configure the endpoint to enable public access.

    IEndpointBehavior serviceRegistrySettings = new ServiceRegistrySettings(DiscoveryType.Public);
    

    En este paso se informa al servicio de retransmisión de que la aplicación se puede encontrar públicamente al examinar la fuente Atom del proyecto.This step informs the relay service that your application can be found publicly by examining the Atom feed for your project. Si establece DiscoveryType en private, un cliente podría seguir accediendo al servicio.If you set DiscoveryType to private, a client could still access the service. Sin embargo, el servicio no aparecería cuando buscase el espacio de nombres de Relay.However, the service wouldn't appear when it searches the Relay namespace. En su lugar, el cliente tendría que conocer de antemano la ruta de acceso del extremo.Instead, the client would have to know the endpoint path beforehand.

  5. Aplique las credenciales de servicio a los puntos de conexión de servicio definidos en el archivo App.config:Apply the service credentials to the service endpoints defined in the App.config file:

    foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
    {
        endpoint.Behaviors.Add(serviceRegistrySettings);
        endpoint.Behaviors.Add(sasCredential);
    }
    

    Como se indicó en el paso anterior, podría haber declarado varios servicios y puntos de conexión en el archivo de configuración.As stated previously, you could have declared multiple services and endpoints in the configuration file. Si lo hubiera hecho, este código recorrería el archivo de configuración y buscaría todos los extremos a los que se deban aplicar las credenciales.If you had, this code would traverse the configuration file and search for every endpoint to which it should apply your credentials. Para este tutorial, el archivo de configuración tiene un solo punto de conexión.For this tutorial, the configuration file has only one endpoint.

Apertura del host de serviciosOpen the service host

  1. Todavía en Main(), agregue la siguiente línea para abrir el servicio.Still in Main(), add the following line to open the service.

    host.Open();
    
  2. Informe al usuario de que se está ejecutando el servicio y explíquele cómo cerrarlo.Inform the user that the service is running, and explain how to shut down the service.

    Console.WriteLine("Service address: " + address);
    Console.WriteLine("Press [Enter] to exit");
    Console.ReadLine();
    
  3. Cuando termine, cierre el host del servicio.When finished, close the service host.

    host.Close();
    
  4. Seleccione Ctrl+Mayús+B para compilar el proyecto.Select Ctrl+Shift+B to build the project.

Ejemplo que hospeda un servicio en una aplicación de consolaExample that hosts a service in a console application

El código de servicio completado debería tener el siguiente formato.Your completed service code should appear as follows. En el código se incluye el contrato de servicio y la implementación de los pasos anteriores del tutorial. Además, hospeda el servicio en una aplicación de consola.The code includes the service contract and implementation from previous steps in the tutorial, and hosts the service in a console application.

using System;
using System.ServiceModel;
using System.ServiceModel.Description;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Description;

namespace Microsoft.ServiceBus.Samples
{
    [ServiceContract(Name = "IEchoContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    public interface IEchoContract
    {
        [OperationContract]
        String Echo(string text);
    }

    public interface IEchoChannel : IEchoContract, IClientChannel { };

    [ServiceBehavior(Name = "EchoService", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    class EchoService : IEchoContract
    {
        public string Echo(string text)
        {
            Console.WriteLine("Echoing: {0}", text);
            return text;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {

            ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.AutoDetect;         

            Console.Write("Your Service Namespace: ");
            string serviceNamespace = Console.ReadLine();
            Console.Write("Your SAS key: ");
            string sasKey = Console.ReadLine();

           // Create the credentials object for the endpoint.
            TransportClientEndpointBehavior sasCredential = new TransportClientEndpointBehavior();
            sasCredential.TokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider("RootManageSharedAccessKey", sasKey);

            // Create the service URI based on the service namespace.
            Uri address = ServiceBusEnvironment.CreateServiceUri("sb", serviceNamespace, "EchoService");

            // Create the service host reading the configuration.
            ServiceHost host = new ServiceHost(typeof(EchoService), address);

            // Create the ServiceRegistrySettings behavior for the endpoint.
            IEndpointBehavior serviceRegistrySettings = new ServiceRegistrySettings(DiscoveryType.Public);

            // Add the Relay credentials to all endpoints specified in configuration.
            foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
            {
                endpoint.Behaviors.Add(serviceRegistrySettings);
                endpoint.Behaviors.Add(sasCredential);
            }

            // Open the service.
            host.Open();

            Console.WriteLine("Service address: " + address);
            Console.WriteLine("Press [Enter] to exit");
            Console.ReadLine();

            // Close the service.
            host.Close();
        }
    }
}

Crear un cliente WCF para el contrato de servicioCreate a WCF client for the service contract

La siguiente tarea consiste en crear una aplicación cliente y definir el contrato de servicio que se implementará más adelante.The next task is to create a client application and define the service contract you'll implement later. Estos pasos son similares a los que se usaron para crear un servicio: definir un contrato, editar un archivo App.config, usar credenciales para conectarse al servicio de retransmisión, etc.These steps resemble the steps used to create a service: defining a contract, editing an App.config file, using credentials to connect to the relay service, and so on. El código utilizado para estas tareas se proporciona en el ejemplo que sigue al procedimiento.The code used for these tasks is provided in the example following the procedure.

  1. Cree un nuevo proyecto en la solución actual de Visual Studio para el cliente:Create a new project in the current Visual Studio solution for the client:

    1. En el Explorador de soluciones, haga clic con el botón derecho en la solución actual (no en el proyecto) y seleccione Agregar > Nuevo proyecto.In Solution Explorer, right-click the current solution (not the project), and select Add > New Project.
    2. En Agregar un nuevo proyecto, seleccione Aplicación de consola (.NET Framework) para C# y seleccione Siguiente.In Add a new project, select Console App (.NET Framework) for C#, and select Next.
    3. Asigne al proyecto el nombre de EchoClient y seleccione Crear.Name project EchoClient and select Create.
  2. En el Explorador de soluciones, en el proyecto EchoClient, haga doble clic en el archivo Program.cs para abrirlo en el editor en caso de que no esté ya abierto.In Solution Explorer, in the EchoClient project, double-click Program.cs to open the file in the editor, if it isn't already open.

  3. Cambie el nombre del espacio de nombres de su nombre predeterminado de EchoClient a Microsoft.ServiceBus.Samples.Change the namespace name from its default name of EchoClient to Microsoft.ServiceBus.Samples.

  4. Instale el paquete NuGet de Service Bus:Install the Service Bus NuGet package:

    1. En el Explorador de soluciones, haga clic con el botón derecho en EchoClient y, después, seleccione Administrar paquetes NuGet.In Solution Explorer, right-click EchoClient and then select Manage NuGet Packages.

    2. Seleccione Examinar y, después, busque y seleccione WindowsAzure.ServiceBus.Select Browse, then search for and select WindowsAzure.ServiceBus. Seleccione Instalar y acepte las condiciones de uso.Select Install, and accept the terms of use.

      Instalar el paquete de Service Bus

  5. Agregue una instrucción using para el espacio de nombres System.ServiceModel en el archivo Program.cs.Add a using statement for the System.ServiceModel namespace in the Program.cs file.

    using System.ServiceModel;
    
  6. Agregue la definición del contrato de servicio al espacio de nombres, como se muestra en el ejemplo siguiente.Add the service contract definition to the namespace, as shown in the following example. Esta definición es idéntica a la definición que se usa en el proyecto Service.This definition is identical to the definition used in the Service project. Agregue este código en la parte superior del espacio de nombres Microsoft.ServiceBus.Samples.Add this code at the top of the Microsoft.ServiceBus.Samples namespace.

    [ServiceContract(Name = "IEchoContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    public interface IEchoContract
    {
        [OperationContract]
        string Echo(string text);
    }
    
    public interface IEchoChannel : IEchoContract, IClientChannel { }
    
  7. Seleccione Ctrl+Mayús+B para compilar el cliente.Select Ctrl+Shift+B to build the client.

Ejemplo del proyecto EchoClientExample of the EchoClient project

En el código siguiente se muestra el estado actual del archivo Program.cs en el proyecto EchoClient.The following code shows the current status of the Program.cs file in the EchoClient project.

using System;
using Microsoft.ServiceBus;
using System.ServiceModel;

namespace Microsoft.ServiceBus.Samples
{

    [ServiceContract(Name = "IEchoContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    public interface IEchoContract
    {
        [OperationContract]
        string Echo(string text);
    }

    public interface IEchoChannel : IEchoContract, IClientChannel { }


    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

Configurar el cliente de WCFConfigure the WCF client

En este paso, creará un archivo App.config para una aplicación cliente básica que accede al servicio creado anteriormente en este tutorial.In this step, you create an App.config file for a basic client application that accesses the service created previously in this tutorial. Este archivo App.config define el contrato, el enlace y el nombre del punto de conexión.This App.config file defines the contract, binding, and name of the endpoint. El código utilizado para estas tareas se proporciona en el ejemplo que sigue al procedimiento.The code used for these tasks is provided in the example following the procedure.

  1. En el Explorador de soluciones, en el proyecto EchoClient, haga doble clic en App.config para abrir el archivo en el editor de Visual Studio.In Solution Explorer, in the EchoClient project, double-click App.config to open the file in the Visual Studio editor.

  2. En el elemento <appSettings>, reemplace los marcadores de posición con el nombre de su espacio de nombres de servicio y la clave SAS que copió en el paso anterior.In the <appSettings> element, replace the placeholders with the name of your service namespace, and the SAS key that you copied in an earlier step.

  3. En el elemento system.serviceModel, agregue un elemento <client>.Within the system.serviceModel element, add a <client> element.

    <?xmlversion="1.0"encoding="utf-8"?>
    <configuration>
      <system.serviceModel>
        <client>
        </client>
      </system.serviceModel>
    </configuration>
    

    En este código se declara que está definiendo una aplicación cliente de estilo WCF.This code declares that you're defining a WCF-style client application.

  4. Dentro del elemento client, defina el nombre, el contrato y el tipo de enlace para el punto de conexión.Within the client element, define the name, contract, and binding type for the endpoint.

    <endpoint name="RelayEndpoint"
                    contract="Microsoft.ServiceBus.Samples.IEchoContract"
                    binding="netTcpRelayBinding"/>
    

    Este código define el nombre del punto de conexión.This code defines the name of the endpoint. En este paso se define el contrato definido en el servicio y el hecho de que la aplicación cliente use TCP para comunicarse con Azure Relay.It also defines the contract defined in the service and the fact that the client application uses TCP to communicate with Azure Relay. El nombre del extremo se usa en el paso siguiente para vincular la configuración de este extremo con el identificador URI del servicio.The endpoint name is used in the next step to link this endpoint configuration with the service URI.

  5. Seleccione Archivo > Guardar todo.Select File > Save All.

Ejemplo del archivo App.configExample of the App.config file

En el código siguiente se muestra el archivo App.config del cliente de eco.The following code shows the App.config file for the Echo client.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <client>
      <endpoint name="RelayEndpoint"
                      contract="Microsoft.ServiceBus.Samples.IEchoContract"
                      binding="netTcpRelayBinding"/>
    </client>
    <extensions>
      <bindingExtensions>
        <add name="netTcpRelayBinding"
                    type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
      </bindingExtensions>
    </extensions>
  </system.serviceModel>
</configuration>

Implementación del cliente de WCFImplement the WCF client

En esta sección, implementará una aplicación cliente básica que accede al servicio que creó anteriormente en este tutorial.In this section, you implement a basic client application that accesses the service you created previously in this tutorial. De forma parecida al servicio, el cliente realiza muchas de las mismas operaciones para acceder a Azure Relay:Similar to the service, the client does many of the same operations to access Azure Relay:

  • Establece el modo de conectividad.Sets the connectivity mode.
  • Crea el identificador URI que localiza el servicio de host.Creates the URI that locates the host service.
  • Define las credenciales de seguridad.Defines the security credentials.
  • Aplica a las credenciales para la conexión.Applies the credentials to the connection.
  • Abre la conexión.Opens the connection.
  • Realiza las tareas específicas de la aplicación.Performs the application-specific tasks.
  • Cierra la conexión.Closes the connection.

Sin embargo, una de las principales diferencias es que la aplicación cliente usa un canal para conectarse al servicio de retransmisión.However, one of the main differences is that the client application uses a channel to connect to the relay service. El servicio utiliza una llamada a ServiceHost.The service uses a call to ServiceHost. El código utilizado para estas tareas se proporciona en el ejemplo que sigue al procedimiento.The code used for these tasks is provided in the example following the procedure.

Implementación de una aplicación clienteImplement a client application

  1. Establezca el modo de conectividad a AutoDetect.Set the connectivity mode to AutoDetect. Agregue el código siguiente dentro del método Main() de la aplicación EchoClient.Add the following code inside the Main() method of the EchoClient application.

    ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.AutoDetect;
    
  2. Defina variables para contener los valores del espacio de nombres del servicio y la clave SAS que se leen desde la consola.Define variables to hold the values for the service namespace, and SAS key that are read from the console.

    Console.Write("Your Service Namespace: ");
    string serviceNamespace = Console.ReadLine();
    Console.Write("Your SAS Key: ");
    string sasKey = Console.ReadLine();
    
  3. Cree el identificador URI que define la ubicación del host en el proyecto de Relay.Create the URI that defines the location of the host in your Relay project.

    Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", serviceNamespace, "EchoService");
    
  4. Cree el objeto de credenciales para el extremo del espacio de nombres de servicio.Create the credential object for your service namespace endpoint.

    TransportClientEndpointBehavior sasCredential = new TransportClientEndpointBehavior();
    sasCredential.TokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider("RootManageSharedAccessKey", sasKey);
    
  5. Cree el generador de canales que carga la configuración que se describe en el archivo App.config.Create the channel factory that loads the configuration described in the App.config file.

    ChannelFactory<IEchoChannel> channelFactory = new ChannelFactory<IEchoChannel>("RelayEndpoint", new EndpointAddress(serviceUri));
    

    Un generador de canales es un objeto de WCF que crea un canal a través del cual se comunican las aplicaciones cliente y de servicio.A channel factory is a WCF object that creates a channel through which the service and client applications communicate.

  6. Aplique las credenciales.Apply the credentials.

    channelFactory.Endpoint.Behaviors.Add(sasCredential);
    
  7. Cree y abra el canal al servicio.Create and open the channel to the service.

    IEchoChannel channel = channelFactory.CreateChannel();
    channel.Open();
    
  8. Escriba la interfaz de usuario básica y la funcionalidad del eco.Write the basic user interface and functionality for the echo.

    Console.WriteLine("Enter text to echo (or [Enter] to exit):");
    string input = Console.ReadLine();
    while (input != String.Empty)
    {
        try
        {
            Console.WriteLine("Server echoed: {0}", channel.Echo(input));
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: " + e.Message);
        }
        input = Console.ReadLine();
    }
    

    El código usa la instancia del objeto de canal como un proxy para el servicio.The code uses the instance of the channel object as a proxy for the service.

  9. Cierre el canal y el generador.Close the channel, and close the factory.

    channel.Close();
    channelFactory.Close();
    

Código de ejemplo de este tutorialExample code for this tutorial

El código completo debería tener el siguiente aspecto.Your completed code should appear as follows. En este código se muestra cómo crear una aplicación cliente, cómo llamar a las operaciones del servicio y cómo cerrar el cliente cuando finaliza la llamada a la operación.This code shows how to create a client application, how to call the operations of the service, and how to close the client after the operation call is finished.

using System;
using Microsoft.ServiceBus;
using System.ServiceModel;

namespace Microsoft.ServiceBus.Samples
{
    [ServiceContract(Name = "IEchoContract", Namespace = "https://samples.microsoft.com/ServiceModel/Relay/")]
    public interface IEchoContract
    {
        [OperationContract]
        String Echo(string text);
    }

    public interface IEchoChannel : IEchoContract, IClientChannel { }

    class Program
    {
        static void Main(string[] args)
        {
            ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.AutoDetect;


            Console.Write("Your Service Namespace: ");
            string serviceNamespace = Console.ReadLine();
            Console.Write("Your SAS Key: ");
            string sasKey = Console.ReadLine();



            Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", serviceNamespace, "EchoService");

            TransportClientEndpointBehavior sasCredential = new TransportClientEndpointBehavior();
            sasCredential.TokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider("RootManageSharedAccessKey", sasKey);

            ChannelFactory<IEchoChannel> channelFactory = new ChannelFactory<IEchoChannel>("RelayEndpoint", new EndpointAddress(serviceUri));

            channelFactory.Endpoint.Behaviors.Add(sasCredential);

            IEchoChannel channel = channelFactory.CreateChannel();
            channel.Open();

            Console.WriteLine("Enter text to echo (or [Enter] to exit):");
            string input = Console.ReadLine();
            while (input != String.Empty)
            {
                try
                {
                    Console.WriteLine("Server echoed: {0}", channel.Echo(input));
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error: " + e.Message);
                }
                input = Console.ReadLine();
            }

            channel.Close();
            channelFactory.Close();

        }
    }
}

Ejecución de las aplicacionesRun the applications

  1. Seleccione Ctrl+Mayús+B para compilar la solución.Select Ctrl+Shift+B to build the solution. Esta acción compila el proyecto de cliente y el proyecto de servicio que creó en los pasos anteriores.This action builds both the client project and the service project that you created in the previous steps.

  2. Antes de ejecutar la aplicación cliente, debe asegurarse de que se está ejecutando la aplicación del servicio.Before running the client application, you must make sure that the service application is running. En el Explorador de soluciones, haga clic con el botón derecho en la solución EchoService y, después, seleccione Propiedades.In Solution Explorer, right-click the EchoService solution, then select Properties.

  3. En Páginas de propiedades, Propiedades comunes > Proyecto de inicio, elija Proyectos de inicio múltiples.In Property Pages, Common Properties > Startup Project, then choose Multiple startup projects. Asegúrese de que EchoService aparece en primer lugar en la lista.Make sure EchoService appears first in the list.

  4. Defina el cuadro Acción para los proyectos EchoService y EchoClient en Iniciar.Set the Action box for both the EchoService and EchoClient projects to Start.

    Páginas de propiedades del proyecto

  5. Seleccione Dependencias del proyecto.Select Project Dependencies. En Proyectos, seleccione EchoClient.In Projects, select EchoClient. En Depende de: , asegúrese de que EchoService está seleccionado.For Depends on, make sure EchoService is selected.

    Dependencias del proyecto

  6. Seleccione Aceptar para cerrar Páginas de propiedades.Select OK to close Property Pages.

  7. Seleccione F5 para ejecutar ambos proyectos.Select F5 to run both projects.

  8. Ambas ventanas de consola se abrirán y le solicitarán el espacio de nombres.Both console windows open and prompt you for the namespace name. Primero debe ejecutarse el servicio, por ello, en la ventana de la consola de EchoService escriba el espacio de nombres y después seleccione Entrar.The service must run first, so in the EchoService console window, enter the namespace and then select Enter.

  9. A continuación, la consola le pedirá la clave SAS.Next, the console prompts you for your SAS key. Escríbala y seleccione ENTRAR.Enter the SAS key and select Enter.

    Este un ejemplo del resultado de la ventana de consola.Here is example output from the console window. Los valores siguientes son solo ejemplos.The values here are just examples.

    Your Service Namespace: myNamespace

    Your SAS Key: <SAS key value>

    La aplicación del servicio imprime en la ventana de la consola la dirección en la que está escuchando, tal y como se muestra en el ejemplo siguiente.The service application prints to the console window the address on which it's listening, as seen in the following example.

    Service address: sb://mynamespace.servicebus.windows.net/EchoService/

    Press [Enter] to exit

  10. En la ventana de la consola de EchoClient escriba la misma información que especificó anteriormente para la aplicación de servicio.In the EchoClient console window, enter the same information that you entered previously for the service application. Especifique los mismos valores de espacio de nombres de servicio y clave SAS para la aplicación cliente.Enter the same service namespace and SAS key values for the client application.

  11. Tras especificar estos valores, el cliente abrirá un canal al servicio y se le solicitará que escriba algo de texto, como se muestra en el siguiente ejemplo de salida de consola.After entering these values, the client opens a channel to the service and prompts you to enter some text as seen in the following console output example.

    Enter text to echo (or [Enter] to exit):

    Escriba algo de texto para enviarlo a la aplicación de servicio y seleccione ENTRAR.Enter some text to send to the service application and select Enter. Este texto se enviará al servicio a través de la operación de servicio de eco y aparecerá en la ventana de la consola del servicio, como se muestra en el siguiente ejemplo de salida.This text is sent to the service through the Echo service operation and appears in the service console window as in the following example output.

    Echoing: My sample text

    La aplicación cliente recibe el valor devuelto de la operación Echo, que es el texto original, y lo imprime en la ventana de consola.The client application receives the return value of the Echo operation, which is the original text, and prints it to its console window. El siguiente texto muestra un ejemplo de la salida de la ventana de consola del cliente.The following text is example output from the client console window.

    Server echoed: My sample text

  12. Puede continuar enviando mensajes de texto desde el cliente al servicio de esta manera.You can continue sending text messages from the client to the service in this manner. Cuando haya terminado, seleccione ENTRAR en las ventanas de las consolas del cliente y el servicio para finalizar ambas aplicaciones.When you're finished, select Enter in the client and service console windows to end both applications.

Pasos siguientesNext steps

Avance al siguiente tutorial:Advance to the following tutorial: