Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Service broker: как автоматически принимать ответ на посланное сообщение  [new]
Yuriy75
Member

Откуда:
Сообщений: 5
Нужно чтобы сервис А посылал запрос сервису В и автоматически получал от него несколько ответов
Попытался изменить пример из пример из msdn http://msdn.microsoft.com/ru-ru/library/cc281517(v=sql.100).aspx . Что то я делаю не так. Может кто подскажет?

1.
-- Создаём объекты для двух сервисов
USE SSBTEST;
GO

CREATE MESSAGE TYPE
        MessageFromA
       VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE
        MessageFromB
		--VALIDATION = NONE;
       VALIDATION = WELL_FORMED_XML;
GO

CREATE CONTRACT ContractAB
      ( MessageFromA
       SENT BY INITIATOR,
        MessageFromB
       SENT BY TARGET
      );
GO

CREATE QUEUE QueueA;

CREATE SERVICE
        ServiceA
       ON QUEUE QueueA
          (ContractAB);
GO

CREATE QUEUE QueueB;

CREATE SERVICE
        ServiceB
       ON QUEUE QueueB
	    (ContractAB);
GO


2.

-- процедура ответа сервиса B на запрос от А
CREATE PROCEDURE ActivProcB
AS
  DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER;
  DECLARE @RecvReqMsg NVARCHAR(100);
  DECLARE @RecvReqMsgName sysname;
  
  print 'Привет';
  WHILE (1=1)
  BEGIN

    BEGIN TRANSACTION;

    WAITFOR
    ( RECEIVE TOP(1)
        @RecvReqDlgHandle = conversation_handle,
        @RecvReqMsg = message_body,
        @RecvReqMsgName = message_type_name
      FROM QueueB
    ), TIMEOUT 5000;

    IF (@@ROWCOUNT = 0)
    BEGIN
      ROLLBACK TRANSACTION;
      BREAK;
    END

    IF @RecvReqMsgName =
       N'MessageFromA'
    BEGIN
    	DECLARE @Msg NVARCHAR(100);
	    DECLARE @I INT;
		SET @I = 1;
		WHILE @I<6 
		BEGIN
		 SET @Msg = N'<MsgFromB>'+CAST (@I AS NVARCHAR(1))+N'</MsgFromB>';
         SEND ON CONVERSATION @RecvReqDlgHandle
               MESSAGE TYPE 
                MessageFromB
               (@Msg);	     
	     SET @I = @I+1;		
		END 				
    END;
      
    COMMIT TRANSACTION;		
  END
GO

-- прицепляем процедуру к очереди
ALTER QUEUE QueueB
    WITH ACTIVATION
    ( STATUS = ON,
  --    RETENTION = ON,
      PROCEDURE_NAME = ActivProcB,
      MAX_QUEUE_READERS = 1000,
      EXECUTE AS SELF
    );
GO


-- процедура для получения ответа сервисом А на ответ от B
CREATE PROCEDURE ActivProcA
AS
  DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER;
  DECLARE @RecvReqMsg NVARCHAR(1000);
  DECLARE @RecvReqMsgName sysname;


BEGIN TRANSACTION;

--WHILE (1=1)
BEGIN

WAITFOR
( RECEIVE TOP(1)
        @RecvReqDlgHandle = conversation_handle,
        @RecvReqMsg = message_body,
        @RecvReqMsgName = message_type_name
	FROM QueueA
), TIMEOUT 5000;

    IF (@@ROWCOUNT = 0)
    BEGIN
      ROLLBACK TRANSACTION;
	--  END CONVERSATION @RecvReqDlgHandle;
    --  BREAK;
    END
	
    IF @RecvReqMsgName =
       N'MessageFromB'
	BEGIN
     SELECT @RecvReqMsg AS ReceivedReplyMsg;	
	END	
   -- ELSE	
	-- END CONVERSATION @RecvReqDlgHandle;
	  COMMIT TRANSACTION;	
END
  
GO

-- призепляем процедуру к очереди сервиса A
ALTER QUEUE QueueA
    WITH ACTIVATION
    ( STATUS = ON,
--      RETENTION = ON,     
      PROCEDURE_NAME = ActivProcA,
      MAX_QUEUE_READERS = 1000,
      EXECUTE AS SELF
    );
GO


3.

DECLARE @InitDlgHandle UNIQUEIDENTIFIER;
DECLARE @RequestMsg NVARCHAR(1000);

BEGIN TRANSACTION;

BEGIN DIALOG @InitDlgHandle
     FROM SERVICE
      ServiceA
     TO SERVICE
      'ServiceB'
     ON CONTRACT
      ContractAB
     WITH
         ENCRYPTION = OFF;
 
-- Send a message on the conversation
SET @RequestMsg =
       N'<MsgFromA>ToB</MsgFromA>';

SEND ON CONVERSATION @InitDlgHandle
     MESSAGE TYPE 
      MessageFromA
     (@RequestMsg);

-- Diplay sent request.
SELECT @RequestMsg AS SentRequestMsg;

COMMIT TRANSACTION;
GO


Если не подключать процедуру к очереди А, то вручную всё принимается

COMMIT TRANSACTION;
GO

  DECLARE @RecvReqDlgHandle UNIQUEIDENTIFIER;
  DECLARE @RecvReqMsg NVARCHAR(1000);
  DECLARE @RecvReqMsgName sysname;


BEGIN TRANSACTION;

WHILE (1=1)
BEGIN

WAITFOR
( RECEIVE TOP(1)
        @RecvReqDlgHandle = conversation_handle,
        @RecvReqMsg = message_body,
        @RecvReqMsgName = message_type_name
	FROM QueueA
), TIMEOUT 5000;

    IF (@@ROWCOUNT = 0)
    BEGIN
      ROLLBACK TRANSACTION;
	  END CONVERSATION @RecvReqDlgHandle;
      BREAK;
    END
	
    IF @RecvReqMsgName =
       N'MessageFromB'
	BEGIN
     SELECT @RecvReqMsg AS ReceivedReplyMsg;	
	END	
    ELSE	
	 END CONVERSATION @RecvReqDlgHandle;
END

GO
18 июн 13, 16:55    [14449283]     Ответить | Цитировать Сообщить модератору
 Re: Service broker: как автоматически принимать ответ на посланное сообщение  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3422
Yuriy75
    IF @RecvReqMsgName =
       N'MessageFromB'
	BEGIN
     SELECT @RecvReqMsg AS ReceivedReplyMsg;	
	END

Чем вы собрались получать селекты, возвращаемые процедурой активации из системного процесса брокера? Они же в космос уходят.
19 июн 13, 05:38    [14451471]     Ответить | Цитировать Сообщить модератору
 Re: Service broker: как автоматически принимать ответ на посланное сообщение  [new]
Yuriy75
Member

Откуда:
Сообщений: 5
Ennor Tiegael, спасибо.

Я по наивности думал что при выполнении в SMS мне результаты select внизу на панельке покажут. Сложил в табличку при приёме - действительно всё работает. Теперь буду пробовать для двух инстансов.
19 июн 13, 09:41    [14451899]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить