Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este tópico descreve como escrever um aplicativo de serviço do WCF (Windows Communication Foundation) sem usar o System.ServiceModel.ServiceHost modelo de objeto associado.
recebendo mensagens
Para estar pronto para receber e processar mensagens, as seguintes etapas são necessárias:
Criar uma associação.
Crie um ouvinte de canal.
Abra o escutador do canal.
Leia a solicitação e envie uma resposta.
Feche todos os objetos de canal.
Criando um vínculo
A primeira etapa para escutar e receber mensagens é criar uma associação. WCF é entregue com várias associações internas ou fornecidas pelo sistema que podem ser usadas diretamente instanciando uma delas. Além disso, você também pode criar sua própria associação personalizada criando uma instância de uma classe CustomBinding, que é o que o código na listagem 1 faz.
O exemplo de código abaixo cria uma instância de System.ServiceModel.Channels.CustomBinding e adiciona um System.ServiceModel.Channels.HttpTransportBindingElement à coleção de elementos, que é uma coleção de elementos de ligação usados para criar a pilha de canais. Neste exemplo, como a coleção de elementos tem apenas a HttpTransportBindingElement, a pilha de canais resultante tem apenas o canal de transporte HTTP.
Criando um ChannelListener
Depois de criar uma associação, chamamos Binding.BuildChannelListener para construir o escutador de canal, no qual o parâmetro de tipo é a forma do canal que será criada. Neste exemplo, estamos usando System.ServiceModel.Channels.IReplyChannel porque queremos escutar mensagens de entrada em um padrão de troca de mensagens de solicitação/resposta.
IReplyChannel é usado para receber mensagens de solicitação e enviar mensagens de resposta de volta. A chamada IReplyChannel.ReceiveRequest retorna um System.ServiceModel.Channels.IRequestChannel, que pode ser usado para receber a mensagem de solicitação e para enviar uma mensagem de resposta de volta.
Ao criar o ouvinte, passamos o endereço de rede no qual ele escuta, nesse caso http://localhost:8080/channelapp. Em geral, cada canal de transporte dá suporte a um ou possivelmente vários esquemas de endereço, por exemplo, o transporte HTTP dá suporte a esquemas http e https.
Também passamos um elemento vazio System.ServiceModel.Channels.BindingParameterCollection ao criar o listener. Um parâmetro de vinculação é um mecanismo para passar parâmetros que controlam como o escutador deve ser criado. Em nosso exemplo, não estamos usando esses parâmetros, portanto, passamos uma coleção vazia.
Escutando mensagens de entrada
Em seguida, chamamos ICommunicationObject.Open no ouvinte e começamos a aceitar canais. O comportamento de IChannelListener<TChannel>.AcceptChannel depende se o transporte é orientado à conexão ou sem conexão. Para transportes orientados à conexão, AcceptChannel bloqueia até que uma nova solicitação de conexão chegue, momento em que ela retorna um novo canal que representa essa nova conexão. Para os transportes sem conexão, como HTTP, AcceptChannel é retornado imediatamente com o único canal criado pelo ouvinte de transporte.
Neste exemplo, o ouvinte retorna um canal que implementa IReplyChannel. Para receber mensagens neste canal, primeiro, chamamos ICommunicationObject.Open nele para colocá-lo em um estado de preparação para a comunicação. Em seguida, chamamos ReceiveRequest, que bloqueia até que uma mensagem chegue.
Lendo a solicitação e enviando uma resposta
Quando ReceiveRequest retorna um RequestContext, obtemos a mensagem recebida usando sua RequestMessage propriedade. Escrevemos a ação e o conteúdo do corpo da mensagem, que presumimos ser uma string (cadeia de caracteres).
Para enviar uma resposta, criamos uma nova mensagem de resposta nesse caso, passando de volta os dados de cadeia de caracteres que recebemos na solicitação. Em seguida, chamamos Reply para enviar a mensagem de resposta.
Como fechar objetos
Para evitar o vazamento de recursos, é muito importante fechar objetos usados nas comunicações quando eles não são mais necessários. Neste exemplo, fechamos a mensagem de solicitação, o contexto da solicitação, o canal e o ouvinte.
O exemplo de código a seguir mostra um serviço básico no qual um ouvinte de canal recebe apenas uma mensagem. Um serviço real continua aceitando canais e recebendo mensagens até que o serviço seja encerrado.
using System;
using System.ServiceModel.Channels;
namespace ProgrammingChannels
{
class Service
{
static void RunService()
{
//Step1: Create a custom binding with just TCP.
BindingElement[] bindingElements = new BindingElement[2];
bindingElements[0] = new TextMessageEncodingBindingElement();
bindingElements[1] = new HttpTransportBindingElement();
CustomBinding binding = new CustomBinding(bindingElements);
//Step2: Use the binding to build the channel listener.
IChannelListener<IReplyChannel> listener =
binding.BuildChannelListener<IReplyChannel>(
new Uri("http://localhost:8080/channelapp"),
new BindingParameterCollection());
//Step3: Listening for messages.
listener.Open();
Console.WriteLine(
"Listening for incoming channel connections");
//Wait for and accept incoming connections.
IReplyChannel channel = listener.AcceptChannel();
Console.WriteLine("Channel accepted. Listening for messages");
//Open the accepted channel.
channel.Open();
//Wait for and receive a message from the channel.
RequestContext request= channel.ReceiveRequest();
//Step4: Reading the request message.
Message message = request.RequestMessage;
Console.WriteLine("Message received");
Console.WriteLine($"Message action: {message.Headers.Action}");
string data=message.GetBody<string>();
Console.WriteLine($"Message content: {data}");
//Send a reply.
Message replymessage=Message.CreateMessage(
binding.MessageVersion,
"http://contoso.com/someotheraction",
data);
request.Reply(replymessage);
//Step5: Closing objects.
//Do not forget to close the message.
message.Close();
//Do not forget to close RequestContext.
request.Close();
//Do not forget to close channels.
channel.Close();
//Do not forget to close listeners.
listener.Close();
}
public static void Main()
{
Service.RunService();
Console.WriteLine("Press enter to exit");
Console.ReadLine();
}
}
}
Imports System.ServiceModel.Channels
Namespace ProgrammingChannels
Friend Class Service
Private Shared Sub RunService()
'Step1: Create a custom binding with just TCP.
Dim bindingElements(1) As BindingElement = {New TextMessageEncodingBindingElement(), _
New HttpTransportBindingElement()}
Dim binding As New CustomBinding(bindingElements)
'Step2: Use the binding to build the channel listener.
Dim listener = binding.BuildChannelListener(Of IReplyChannel)(New Uri("http://localhost:8080/channelapp"), _
New BindingParameterCollection())
'Step3: Listening for messages.
listener.Open()
Console.WriteLine("Listening for incoming channel connections")
'Wait for and accept incoming connections.
Dim channel = listener.AcceptChannel()
Console.WriteLine("Channel accepted. Listening for messages")
'Open the accepted channel.
channel.Open()
'Wait for and receive a message from the channel.
Dim request = channel.ReceiveRequest()
'Step4: Reading the request message.
Dim message = request.RequestMessage
Console.WriteLine("Message received")
Console.WriteLine("Message action: {0}", message.Headers.Action)
Dim data = message.GetBody(Of String)()
Console.WriteLine("Message content: {0}", data)
'Send a reply.
Dim replymessage = Message.CreateMessage(binding.MessageVersion, _
"http://contoso.com/someotheraction", data)
request.Reply(replymessage)
'Step5: Closing objects.
'Do not forget to close the message.
message.Close()
'Do not forget to close RequestContext.
request.Close()
'Do not forget to close channels.
channel.Close()
'Do not forget to close listeners.
listener.Close()
End Sub
Public Shared Sub Main()
Service.RunService()
Console.WriteLine("Press enter to exit")
Console.ReadLine()
End Sub
End Class
End Namespace