Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
вот и я добрался до брокера))
нужна натификация с сервера на клиент
Подписчиков планируется немного, но события могут происходить часто.
Посмотрел в сторону SQLDepedency c квери натификейшен.
Поплохело:
При переподписке каждый раз создается сервис, очередь, а уж убивание процедурой активации самой себя.....


Сейчас попробовал сделать так.

клиент вызывает процедуру подписки. Она создает диалог, и возвращает клиенту хендл диалога.
транзакции пока убрал, для лучшего понимания

DECLARE 
	@ch UNIQUEIDENTIFIER,	
	@msg xml

;BEGIN DIALOG CONVERSATION @ch
	FROM SERVICE [sbs_Source_Service]
	TO SERVICE 'sbs_Source_Service'
		ON CONTRACT [sbc_skif_PostCacheEdit]
		WITH ENCRYPTION = OFF

во второй конекшене клиент начинает читать очередь


	BEGIN
		
		--BEGIN TRANSACTION
		declare 
			@msg xml,
			@nom int

		WAITFOR
		(
			RECEIVE TOP (1)
				@nom = message_sequence_number,
				@msg = CAST(message_body AS XML)
				--conversation_handle,
				--message_type_name,

			FROM [cache].[Reset_Queue]
		), TIMEOUT 1001000
		
		select @nom, @msg
	end

на сервере есть табличка с текущими подписчиками и их хендлами, времея от времени подписчикам отправляется сообщение с скл.

declare @msg xml
set @msg = (select top 10 [@ID] = ID from nsi.Catalog for xml path)
;SEND ON CONVERSATION '03E85588-0100-E611-80E4-00155D008E05' MESSAGE TYPE [sbmt_skif_subdcribe](@msg)


Собственно вопрос
сейчас у меня нет процедуры активации, и она не нужна.
1. Как - нибудь можно закрыть диалог на второй стороне?
2 Можно рециклить диалоги, вместо закрытия?
3 То что один сервис участвует с двух сторон диалога - это нормально?
11 апр 16, 20:04    [19044491]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
invm
Member

Откуда: Москва
Сообщений: 9724
Mike_za
1. Как - нибудь можно закрыть диалог на второй стороне?
Можно. Послать второй стороне сообщение типа http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog и обработать его соответствующим образом.
Mike_za
2 Можно рециклить диалоги, вместо закрытия?
Можно. Просто не закрывайте диалог.
Mike_za
3 То что один сервис участвует с двух сторон диалога - это нормально?
Да.
11 апр 16, 20:23    [19044553]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
invm,
У меня проблема с пониманием что есть "второй сторона.
По сути первый конекшен создал диалог, и общается через него с кем угодно, кто отправляет send с этим хендл.

Как сервер понимет, что END CONVERSATION вызван второй стороной.
Или суть в 2х собщениях об окончании диалога подряд?

Ну и еще. Моя реализация она вообще для промышленного использования подходит?
11 апр 16, 21:51    [19044835]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
o-o
Guest
Для тех, кто мне подобно решил,
что данная тема имеет прямое отношение к Натику из Баку,
спешу сообщить: мыслить надо ширше или даже ширее:
"натификация" -- это вступление сервера в НАТО
11 апр 16, 22:00    [19044857]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
invm
Member

Откуда: Москва
Сообщений: 9724
Mike_za
Как сервер понимет, что END CONVERSATION вызван второй стороной.
Или суть в 2х собщениях об окончании диалога подряд?
Суть в том, что END CONVERSATION завершает диалог и отправляет противоположной стороне сообщение http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog. В ответ на это сообщение вторая сторона также должна завершить диалог.
Другие варианты приводят к проблемам - How to prevent conversation endpoint leaks
Mike_za
Ну и еще. Моя реализация она вообще для промышленного использования подходит?
Почему нет? Другую схему через Service Broker придумать сложно :)
Можете еще поиграться, если хотите, с внешней активацией.
11 апр 16, 23:08    [19045002]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
invm,

Внешняя активация, если я правильно понял, запускает внешний процесс когда возникнет надобность. И экономится постоянный конекшен? Реально они в 2008 это добавиили какой-то расширенной допонительной комплнентой.
Действительно оно того стоит, когда события происходят раз в 5 минут хотя бы?
11 апр 16, 23:39    [19045044]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
invm
Member

Откуда: Москва
Сообщений: 9724
Mike_za
Внешняя активация, если я правильно понял, запускает внешний процесс когда возникнет надобность.
Не обязательно. Этот механизм подробно рассматривается в книге Pro SQL Server 2008 Service Broker
Mike_za
Действительно оно того стоит, когда события происходят раз в 5 минут хотя бы?
Не зная деталей сложно давать рекомендации. Что выбрать решать вам, после анализа и тестирования.
12 апр 16, 00:11    [19045073]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
invm,

Большой спасибо!
12 апр 16, 00:17    [19045077]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
и вновь про Target.
а как в случае сервиса общающегося самого с собой отправить сообщение со стороны таргета?

create contract [contract_Cache_Actuality]
(
	[st_Subscribe]		SENT BY INITIATOR,
	[st_Reset_Cache_Item]	SENT BY TARGET
)

	;BEGIN DIALOG CONVERSATION @Dialog_Handle
			FROM SERVICE [service_Cache_Actuality] TO SERVICE 'service_Cache_Actuality' ON CONTRACT [contract_Cache_Actuality]
			WITH ENCRYPTION = OFF;
		
		;SEND ON CONVERSATION @Dialog_Handle MESSAGE TYPE [st_Subscribe]('Подпиши меня');


если теперь из любого другого конекшена я пытаюсь с этим @Dialog_Handle отправить сообщение, оно также считается отправленным от Source

WAITFOR
(
	RECEIVE TOP (1)
		@nom = message_sequence_number,
		@msg = CAST(message_body AS varchar(max))
		--conversation_handle,
		--message_type_name,

	FROM [cache].[queue_Cache_Actuality]
), TIMEOUT 1001000

select @nom, @msg

set @Dialog_Handle = (select top 1 Dialog_Handle from cache.Subscription order by ID desc)
;SEND ON CONVERSATION @Dialog_Handle MESSAGE TYPE [st_Reset_Cache_Item](@msg);


Msg 8432, Level 16, State 1, Line 29
Данное сообщение не может быть отправлено, так как тип сообщений "st_Reset_Cache_Item" помечен в контракте как SENT BY TARGET, однако служба является инициатором.
12 апр 16, 14:06    [19047299]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8584
Mike_za,

автор
сервиса общающегося самого с собой

Таких не бывает, всегда общаются два "контрагента".
12 апр 16, 14:27    [19047419]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
invm
Member

Откуда: Москва
Сообщений: 9724
Mike_za
а как в случае сервиса общающегося самого с собой отправить сообщение со стороны таргета?
Для нужного типа сообщения поставить в контракте SENT BY ANY.
12 апр 16, 15:10    [19047750]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
invm
Mike_za
а как в случае сервиса общающегося самого с собой отправить сообщение со стороны таргета?
Для нужного типа сообщения поставить в контракте SENT BY ANY.


это я понимаю. по сути я отправителем, и кладу сообщения и забираю сообщения.
как же мне тогда закрыть диалог со стороны Target-а?
12 апр 16, 15:24    [19047864]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
invm
Member

Откуда: Москва
Сообщений: 9724
Mike_za
как же мне тогда закрыть диалог со стороны Target-а?
Я же уже писал: выполнить END CONERSATION и обработать сообщение закрытия диалога (тоже выполнить END CONVERSATION) в инициаторе.

Так завершать диалог нужно с любой стороны.
12 апр 16, 15:50    [19048026]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
продолжаю, как уже понимаю делать велосипед :((
после некоторого времени, стало очевидно, что закрыть диалог не проблема.

но теперь проблема, как получить второй хендл диалога,
не выгребая все очередь, а только сообщения внутри текущего диалога

ведь я общаюсь сам с собой, и не могу узнать ИД второй стороны....

можно как-то проще сделать?

		
;BEGIN DIALOG CONVERSATION @Dialog_Handle
	FROM SERVICE [service_Cache_Actuality] TO SERVICE 'service_Cache_Actuality' ON CONTRACT [contract_Cache_Actuality]
	WITH ENCRYPTION = OFF;

-- устанавливается соединения, создается вторая точка
;SEND ON CONVERSATION @Dialog_Handle MESSAGE TYPE [st_Subscribe]('Подпиши меня');

select 
	@Dialog_Handle_2 = E2.conversation_handle
from
	sys.conversation_endpoints E1
	inner join sys.conversation_endpoints E2 on E2.conversation_id = E1.conversation_id and E2.is_initiator = 0
where 
	E1.conversation_handle = @Dialog_Handle
12 апр 16, 20:14    [19049270]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
invm
Member

Откуда: Москва
Сообщений: 9724
Mike_za
ведь я общаюсь сам с собой, и не могу узнать ИД второй стороны....
Что вы пытаетесь сделать?
12 апр 16, 21:04    [19049418]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
invm,

Я пытаюсь повесить несколько подписок.
Клиенты пописываются, и во втором соединении ждут сообщений.

При определенных событиях на сервере, части клиентов отправляются сообщения.
Каждый клиент слушает свои индивидуальные сообщения, для этого нужен фильр по хендлу диалога.
Либо отдельная очередь + сервис на каждую подписку (так в примере из книжки, как раз)

Вопрос как получить хенд диалога, и забирать только свои сообщения
12 апр 16, 21:26    [19049495]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
invm
Member

Откуда: Москва
Сообщений: 9724
Mike_za
Вопрос как получить хенд диалога, и забирать только свои сообщения
При обработке сообщения на создание подписки сохранять в служебной таблице хендл диалога и тип сообщения.
При рассылке уведомлений выбирать из этой таблицы хендлы, соответствующие типу отсылаемого уведомления.
12 апр 16, 22:30    [19049695]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Tip4ik
Member

Откуда: Москва
Сообщений: 15
Mike_za
invm,

Я пытаюсь повесить несколько подписок.
Клиенты пописываются, и во втором соединении ждут сообщений.

При определенных событиях на сервере, части клиентов отправляются сообщения.
Каждый клиент слушает свои индивидуальные сообщения, для этого нужен фильр по хендлу диалога.
Либо отдельная очередь + сервис на каждую подписку (так в примере из книжки, как раз)

Вопрос как получить хенд диалога, и забирать только свои сообщения


Вообще по задумке SB логично, чтобы один подписчик был равен одному сервису(внешнему или внутреннему).
Если же у вас поток сообщений совершенно мелкий, то вы можете элементарно сделать разные контракты для каждого подписчика, что в итоге даст по одному диалогу на одного подписчика.
Никак не могу понять вашего желания различать диалоги еще до вычитывания... Ведь вам важно, чтобы любое сообщение нотификации было обработано! Соответственно вычитывайте все сообщения из очереди, а потом внутри процы анализируйте msg_type или какие-то ещё свойства, а дальше действуйте как считаете нужным.
12 апр 16, 22:46    [19049725]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
Tip4ik,

Пусть 10 диалогов, в некий момент 5 подписчиков получают каждый свою хмлку.
Вы предлагаете всем 5 отправить суммарный пакет? Что он сам разбирался?
12 апр 16, 22:56    [19049745]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
invm
Mike_za
Вопрос как получить хенд диалога, и забирать только свои сообщения
1.При обработке сообщения на создание подписки сохранять в служебной таблице хендл диалога и тип сообщения.
2.При рассылке уведомлений выбирать из этой таблицы хендлы, соответствующие типу отсылаемого уведомления.

Как на 1м этапе можно получить второй хенд , не используя системную вьюху с endpoints?
12 апр 16, 22:59    [19049753]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Tip4ik
Member

Откуда: Москва
Сообщений: 15
Mike_za
Tip4ik,

Пусть 10 диалогов, в некий момент 5 подписчиков получают каждый свою хмлку.
Вы предлагаете всем 5 отправить суммарный пакет? Что он сам разбирался?


нет, предлагаю отправить каждому получателю в его диалог его XML.
В этот момент предлагаю работать вам только с теми диалогами для которых вы являетесь инициатором. Тогда все диалоги у вас будут создаваться только по инициативе событий нотификации, соответственно вы их можете сохранить в отдельную таблицу, как вам уже предложили выше в любой удобной для вас форме в плоть до handle, notification_type, recipient, а в следующий раз в сначала проверять наличие диалога в этой таблице, а уж если нет, то создавать новый.

з.ы. не забывайте удалять из этой таблицы диалоги в момент закрытия, не важно сами вы его инициировали или вам пришла команда от др. стороны.
12 апр 16, 23:52    [19049923]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
invm
Member

Откуда: Москва
Сообщений: 9724
Mike_za
Как на 1м этапе можно получить второй хенд , не используя системную вьюху с endpoints?
Какой второй? Нет никаких вторых.
Хендл берется из полученного сообщения - столбец conversation_handle при чтении из очереди инструкцией receive.
13 апр 16, 00:14    [19049989]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
автор
The usage pattern where the initiator or sender knows in advance the conversation handle and attempts to RECEIVE only it's own messages is indicative of an defective application design. Due to the long lived and persisted nature of Service Broker conversations one cannot get this pattern to work as he/she intends. In time the queue will fill with abandoned conversations/messages.

The proper pattern must be event driven and the application should always to RECEIVE the next message in queue w/o a WHERE clause.

Wednesday, July 23, 2008 8:52 AM
Reply | Quote

Remus Rusanu4,260 Points
Moderator

Кажись про меня...
13 апр 16, 00:31    [19050027]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
invm,

Мне для чтения из очереди инструкцией ресиве хотелось указать в фильтре хендл, котопый я не могу получить (не через жопу... Простите)
13 апр 16, 00:34    [19050033]     Ответить | Цитировать Сообщить модератору
 Re: Натификация с сервера  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
+
автор
I think you understand very well how your application is working and how is using SSB to achieve its goals. You already said this is working fine in several sites and you have probably found and ironed out all the possible issues by now. My main concern when I see a post like yours is what happens if somebody googles this problem, finds your solution and merrily implements it. Your solution works fine for your case, but it will fail on a 'true' Broker application.
Let me clarify what I mean by this. You application is basically a queue application, not a messaging application. You are leveraging SSB queues because they give you some nice semantics like conversation group locking or non-pulling WAITFOR in RECEIVE. When I say a 'true' Broker application I'm referring to distributed applications that use messaging as a communication means, leverage features like routing for indiration of service location and are completely transparent to the actual location of services and conversation endpoints. So I think is worth calling out what makes you case special and why are you able to pull off such an unothodox use of conversations. I'm not sure though I understood everything correctly, but here is my take on why this is working fine for you:
your application is always local, contained within one database (ie. sender and target are within the same database) so you can affort to look up the 'target' endpoint after you create the initiator.
your conversations are transient, disposable and tied to the lifetime of the client ('processor') process. Your conversations are basically an 'in database' socket IPC and they are deleted (timed out) if the process that start it dies.
In a 'true' Broker application both these assumption would be false. Services should never assume the other service they are talking to is local. And conversations should only be tied to transaction lifetimes, not processes. Ie. a process can start a conversation, send a message, commit then exit (die) and another process should be able to pick up the response and process it.

Let me make clear that I don't mean 'true' Broker applications in the sense of 'right' or 'correct'. I mean it in the sense of what was the original problem SSB tried to address. Other usages like local asynchronous procedure execution through activation or just a queue with FIFO semantics are just as valid. But when any if these 'local' and specific usages it is tried to be expanded into a distributed application, problems start to arrise.


Аааа. Все не так уж ужасно.. Типа это "не тру сервис броке аппликейшкн"
Тогда можно продолжить тянуть кота)))
13 апр 16, 00:44    [19050049]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить