Los scripts tienen tres partes, en la primera configuramos toda la estructura, en la segunda enviamos un mensaje y en la tercera recibimos el mensaje y acabamos la conversación.
CREATE XML SCHEMA COLLECTION MiEsquemaEnvio AS
N‘<schema xmlns=”http://www.w3.org/2001/XMLSchema” >
<element name=”Clientes”>
<complexType>
<sequence>
<element name=”idCliente” type=”int” />
<element name=”Nombre” type=”string”/>
</sequence>
</complexType>
</element>
</schema>
‘
GO
CREATE XML SCHEMA COLLECTION MiEsquemaRecepcion AS
N‘<schema xmlns=”http://www.w3.org/2001/XMLSchema” >
<element name=”Clientes”>
<complexType>
<sequence>
<element name=”idCliente” type=”int” />
<element name=”CreditoConcedido” type=”decimal”/>
</sequence>
</complexType>
</element>
</schema>
‘
Creando Tipos de mensajes basados en esos esquemas
CREATE MESSAGE TYPE [Envio] VALIDATION= VALID_XML
WITH SCHEMA COLLECTION MiEsquemaEnvio;
CREATE MESSAGE TYPE [Recepcion]
VALIDATION=VALID_XML
WITH SCHEMA COLLECTION MiEsquemaRecepcion;
GO
Creando contratos que permitan enviar y recibir mensajes de este tipo
CREATE CONTRACT [PeticionCredito]
([Envio] SENT BY INITIATOR,[Recepcion] SENT BY TARGET)
Creando las colas para soportar estas cosas
CREATE QUEUE Peticion WITH STATUS=ON;
CREATE QUEUE Respuesta WITH STATUS=ON;
Creando servicios que usen estas colas
CREATE SERVICE SrvPeticion ON
QUEUE [Peticion] ( PeticionCredito);
CREATE SERVICE SrvRespuesta ON
QUEUE [Respuesta] ( PeticionCredito);
Enviando mensajes basados en esos servicios
DECLARE @Cliente xml(MiEsquemaEnvio)
DECLARE @message_type_name NVARCHAR(256)
DECLARE @conversationhandle UNIQUEIDENTIFIER
DECLARE @Conversacion TABLE(
service_instance_id UNIQUEIDENTIFIER,
handle UNIQUEIDENTIFIER,
message_sequence_number BIGINT,
service_name NVARCHAR(512),
service_contract_name NVARCHAR(256),
message_type_name NVARCHAR(256),
validation NCHAR,
message_body VARBINARY(MAX)) ;
Set @cliente=
CAST(N‘<Clientes>
<idCliente>10</idCliente>
<Nombre>Miguel Egea (Petición 1)</Nombre>
</Clientes>’ as xml(MiEsquemaEnvio))
BEGIN TRANSACTION
BEGIN DIALOG @conversationhandle
FROM SERVICE SrvPeticion
TO SERVICE ‘SrvRespuesta’
ON CONTRACT PeticionCredito
WITH ENCRYPTION=OFF;
SEND ON CONVERSATION @conversationhandle
MESSAGE TYPE Envio (@cliente)
COMMIT
Una vez que hemos enviado el mensaje, veamos como recibirlo en el destino.
DECLARE @Cliente xml(MiEsquemaEnvio)
Declare @conversationhandle uniqueidentifier
declare @saldoCliente as xml(MiEsquemaRecepcion)
Declare @id int
DECLARE @Conversacion TABLE(
service_instance_id UNIQUEIDENTIFIER,
handle UNIQUEIDENTIFIER,
message_sequence_number BIGINT,
service_name NVARCHAR(512),
service_contract_name NVARCHAR(256),
message_type_name NVARCHAR(256),
validation NCHAR,
message_body VARBINARY(MAX)) ;
BEGIN TRANSACTION
WAITFOR
(
RECEIVE TOP (1)
conversation_group_id,
conversation_handle,
message_sequence_number,
service_name,
service_contract_name,
message_type_name,
validation,
message_body
FROM Respuesta
INTO @Conversacion
);
SELECT @conversationhandle=handle,
@cliente=message_body
FROM @Conversacion
Tenemos el mensaje, procesarlo ahora pertenece al proceso de negocio, vamos a usar el método value para leer el XML simplificando este proceso para centrarnos en el envio y tratamiento.
set @id= @cliente.value(‘(/Clientes/idCliente)[1]’, ‘int’ )
SET @SaldoCliente=
CAST(N‘<Clientes>
<idCliente>’ + CAST(@id AS NVARCHAR(10))
+‘</idCliente>
<CreditoConcedido>1000.36</CreditoConcedido>
</Clientes>’ as xml(MiEsquemaRecepcion));
SEND ON CONVERSATION @conversationhandle
MESSAGE TYPE Recepcion(@SaldoCliente)
END CONVERSATION @conversationHandle;
COMMIT
El que envió la petición ahora recibe la respuesta y la procesa como estime oportuno
WHILE (1=1)
BEGIN
BEGIN TRANSACTION
WAITFOR
(
RECEIVE TOP(1)
conversation_group_id,
conversation_handle,
message_sequence_number,
service_name,
service_contract_name,
message_type_name,
validation,
message_body
FROM Peticion
INTO @Conversacion
WHERE conversation_handle = @ConversationHandle
);
SELECT CAST(Message_body as XML) FROM @CONVERSACION
COMMIT
SELECT @message_type_name=message_type_name
FROM @CONVERSACION
IF @message_type_name =
‘http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog’
OR @message_type_name =
‘http://schemas.microsoft.com/SQL/ServiceBroker/Error’
BEGIN
select ‘acabo’
END CONVERSATION @ConversationHandle ;
BREAK;
END
END
Esto es un ejemplo de envio y recepción de mensajes mediante Service Broker, aunque hayamos puesto bucles infinitos y waitfors, no entendamos esto como una espera activa ni muchísimo menos, El tipo de aplicaciones que se desarrollen y su complejidad dependrá muchísimo de los requisitos de negocio, SB sin embargo es una plataforma robusta estable, escalable y muy fácilmente configurable que puede permitir hacer aplicaciones asíncronas fácilmente.