«Тип уведомления <MessageType>был неожиданным». зарегистрирован SSBEA и мое приложение никогда не называется - PullRequest
3 голосов
/ 06 декабря 2010

Я использую SQL Server 2005 Standard Edition с установленным внешним активатором. У меня есть следующий код на вкладке SSMS:

-- Begin a conversation and send a request message
DECLARE @InitDlgHandle UNIQUEIDENTIFIER;
DECLARE @RequestMsg NVARCHAR(100);

BEGIN TRANSACTION;
    BEGIN DIALOG @InitDlgHandle
        FROM SERVICE [//abc/XYZ/InitiatorPostService]
        TO SERVICE N'//abc/XYZ/TargetPostService'
        ON CONTRACT [//abc/XYZ/PostContract]
        WITH ENCRYPTION = OFF;

    SELECT @RequestMsg = N'<RequestMsg>Message for Target service.</RequestMsg>';

    SEND ON CONVERSATION @InitDlgHandle
        MESSAGE TYPE [//abc/XYZ/RequestPostMessage](@RequestMsg);

    SELECT @RequestMsg AS SentRequestMsg, @InitDlgHandle AS ConversationHandle;
COMMIT TRANSACTION;
GO

Когда я запускаю его, я получаю ожидаемый результат в области результатов. В EATrace.log я получаю сообщение об ошибке «Тип сообщения уведомления // abc / XYZ / RequestPostMessage был неожиданным».

-- Create message types
CREATE MESSAGE TYPE [//abc/XYZ/RequestPostMessage]  VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE [//abc/XYZ/ReplyPostMessage]    VALIDATION = WELL_FORMED_XML;
GO

-- Create contract
CREATE CONTRACT [//abc/XYZ/PostContract]
     ([//abc/XYZ/RequestPostMessage] SENT BY INITIATOR,
     [//abc/XYZ/ReplyPostMessage] SENT BY TARGET
);
GO

-- Create target queue and service
CREATE QUEUE TargetPostQueue WITH RETENTION = ON;
CREATE SERVICE [//abc/XYZ/TargetPostService]
     ON QUEUE TargetPostQueue([//abc/XYZ/PostContract]);
GO

-- Create the initiator queue and service
CREATE QUEUE InitiatorPostQueue WITH RETENTION = ON;
CREATE SERVICE [//abc/XYZ/InitiatorPostService]
     ON QUEUE InitiatorPostQueue([//abc/xyz/PostContract]);
GO

-- Create a notification for External Activator
CREATE QUEUE NotificationPostQueue
CREATE SERVICE [//abc/xyz/NotificationPostService]
    ON QUEUE NotificationPostQueue([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification])
CREATE EVENT NOTIFICATION EventQueueActivation
    ON QUEUE [TargetPostQueue]
    FOR QUEUE_ACTIVATION
    TO SERVICE '//abc/xyz/NotificationPostService', 'current_database';
GO

-- Security
GRANT CONNECT TO [**Company**\**Machine**$]                          -- allow CONNECT to the notification database
GRANT RECEIVE ON TargetPostQueue TO [**Company**\**Machine**$]       -- allow RECEIVE from the service queue
GRANT RECEIVE ON NotificationPostQueue TO [**Company**\**Machine**$] -- allow RECEIVE from the notifcation queue
GRANT REFERENCES ON SCHEMA::dbo TO [**Company**\**Machine**$]        -- allow REFRENCES right on the notification queue schema

-- allow VIEW DEFINITION on the target service
GRANT VIEW DEFINITION ON SERVICE::[//abc/xyz/TargetPostService] TO [**Company**\**Machine**$]

-- allow VIEW DEFINITION on the notification service
GRANT VIEW DEFINITION ON SERVICE::[//abc/xyz/NotificationPostService] TO [**Company**\**Machine**$]
GO

В EAService.config нет ничего, что сообщало бы EA, какие типы сообщений следует ожидать. Почему я получаю эту ошибку вместо того, чтобы EA запускала приложение, указанное в его файле конфигурации? У меня контракт настроен неправильно?

** Недавно добавленный раздел ниже: **

По предложению Ремуса я добавил следующее:

-- Create a notification for External Activator
CREATE QUEUE NotificationPostQueue

CREATE SERVICE [//abc/xyz/NotificationPostService]
    ON QUEUE NotificationPostQueue([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification])

CREATE EVENT NOTIFICATION EventQueueActivation
    ON QUEUE [TargetPostQueue]
    FOR QUEUE_ACTIVATION
    TO SERVICE '//abc/xyz/NotificationPostService', 'current_database';
GO

Но когда я изменяю имя NotificationService в файле конфигурации с "// abc / xyz / TargetPostService" на "// abc / xyz / NotificationPostService", я получаю ошибку "ERROR = 31, Служба уведомлений // abc / xyz / NotificationPostService не существует "в EATrace.log, когда я запускаю службу. Однако этот сервис указан в sys.services.

** Ошибка 31 устранена, теперь проблема в том, что мое приложение не вызывается **

Я использовал пример приложения из блога группы разработчиков Service Broker, добавляя ведение журнала в целях отладки. Он записывает файл журнала сразу после запуска, прежде чем делать что-либо еще. Я проверил его, запустив его из VS2010, и это прекрасно работает, но когда я отправляю сообщение, используя код в начале этого вопроса, больше не создается. Поэтому я знаю, что мое приложение не запускается EA. Как я могу диагностировать, почему это происходит? Пути в моем файле EAService.config являются правильными. Вот весь файл:

<?xml version="1.0" encoding="utf-8"?>
<Activator xmlns="http://schemas.microsoft.com/sqlserver/2008/10/servicebroker/externalactivator"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://schemas.microsoft.com/sqlserver/2008/10/servicebroker/externalactivator EAServiceConfig.xsd"
           >
  <NotificationServiceList>
    <NotificationService name="//abc/xyz/NotificationPostService" id="100" enabled="true">
      <Description>My test notification service</Description>
      <ConnectionString>
        <!-- All connection string parameters except User Id and Password should be specificed here -->
        <Unencrypted>server=**MyServer**\**MyInstance**;database=CompanyRehabManagement;Application Name=External Activator;Integrated Security=true;</Unencrypted>
      </ConnectionString>
    </NotificationService>
  </NotificationServiceList>
  <ApplicationServiceList>
    <ApplicationService name="Company.xyz.EAProcessor" enabled="true">
      <OnNotification>
        <ServerName>**MyServer**\**MyInstance**</ServerName>
        <DatabaseName>**MyDbName**</DatabaseName>
        <SchemaName>dbo</SchemaName>
        <QueueName>TargetPostQueue</QueueName>
      </OnNotification>
      <LaunchInfo>
        <ImagePath>C:\Project\Pathway\Source\Company.xyz\Company.xyz.EAProcessor\bin\Debug\Company.xyz.EAProcessor.exe</ImagePath>
        <CmdLineArgs> %sqlserver% %database% %schema% %queue% </CmdLineArgs>
        <WorkDir>C:\Project\Pathway\Source\Company.xyz\Company.xyz.EAProcessor</WorkDir>
      </LaunchInfo>
      <Concurrency min="1" max="1" />
    </ApplicationService>
  </ApplicationServiceList>
  <LogSettings>
    <LogFilter>
      <TraceFlag>All Levels</TraceFlag>
      <TraceFlag>All Modules</TraceFlag>
      <TraceFlag>All Entities</TraceFlag>
    </LogFilter>
  </LogSettings>
</Activator>

Использую ли я правильное имя очереди? Есть ли другие возможные ошибки в этом файле? Что еще я могу сделать, чтобы диагностировать это? Это разговор, который происходит:

conversation_id,                      is_initiator, conversation_handle,                  local_service,                  remote_service,                 service_contract,       state_desc, far_broker_instance,                  security_timestamp,      send_sequence, receive_sequence, end_dialog_sequence, system_sequence
411C6F74-B29F-4C47-A538-1B9C900F49BD, 1,            7E7DD27A-E102-E011-93D2-0004239AA238, //abc/xyz/InitiatorPostService, //abc/xyz/TargetPostService,    //abc/xyz/PostContract, CONVERSING, 083E1179-A1C3-4414-A1A6-67238E3879CE, 1900-01-01 00:00:00.000, 1,             0,                -1,                  0
411C6F74-B29F-4C47-A538-1B9C900F49BD, 0,            817DD27A-E102-E011-93D2-0004239AA238, //abc/xyz/TargetPostService,    //abc/xyz/InitiatorPostService, //abc/xyz/PostContract, CONVERSING, 083E1179-A1C3-4414-A1A6-67238E3879CE, 2010-12-08 16:10:59.260, 0,             1,                -1,                  0

Ответы [ 4 ]

3 голосов
/ 09 декабря 2010

Когда вы создаете уведомление о событии, вы должны использовать «текущую базу данных» (без подчеркивания), а не «current_database». 'current database' - это специальное значение, которое будет соответствовать любому идентификатору брокера текущей базы данных, тогда как в вашем случае уведомление о событии пытается отправить сообщение-уведомление службе с идентификатором брокера = 'current_database'.

2 голосов
/ 07 декабря 2010

Внешний активатор не отслеживает вашу очередь, вместо этого он отслеживает очередь уведомлений.Внешняя активация управляется подпиской на уведомления о событиях, что-то вроде:

CREATE EVENT NOTIFICATION EventQueueActivation
ON QUEUE [TargetPostQueue]
FOR QUEUE_ACTIVATION
TO SERVICE '...','...';

Так что SSBEA нуждается в своей собственной очереди, в которую он будет получать уведомления QUEUE_ACTIVATION.В этой очереди должна быть служба, поддерживающая контракт http://schemas.microsoft.com/SQL/Notifications/PostEventNotification (контракт на уведомления о событиях).

Похоже, что в вашем случае SSBEA настроен на прослушивание уведомлений на самом TargetPostQueue итаким образом он получает ваши пользовательские сообщения приложения вместо ожидаемых уведомлений о событиях.

1 голос
/ 05 июня 2014

Я просто хотел бы добавить, что имя attibute ApplicationService в EAConfig должно совпадать с именем TargetService в SQL.Поэтому, если ваша целевая служба называется PostInsertedRecordsService, то атрибут имени приложения также будет PostInsertedRecordsService.

1 голос
/ 07 декабря 2010

Что касается проблемы с ОШИБКОЙ 31, упомянутой в конце вашего вопроса, пожалуйста, убедитесь, что строка подключения в файле конфигурации внешнего активатора явно задает исходный каталог для базы данных, в которой расположена служба уведомлений.В противном случае он попытается найти его в master db, что, очевидно, приведет к сбою.

Пример доступен в Блоге команды брокера служб .

...