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

Откуда: Харьков, Украина
Сообщений: 1462
Привет всем!

Вопрос несколько потрепан, но найти навскидку удобоваримое и простое решение по сабжу не удалось.
Итак, что имеем. Есть двухуровневое приложение. Предположим, это некий корпоративный календарь. У каждого пользователя есть WinForms приложение. С помощью которого можно создавать события в корпоративном календаре. Пользователи могут руками обновить имеющиеся события календаря. Могут создать новое событие. Не обязательно средствами своего приложения (так получилось :( ). Т.е. единственная точка, в которой известно о создании нового события - это некая хранимая процедура на сервере.
И вот - возникает вопрос. Как на стороне SQL Server можно сгенерировать некое уведомление о создании нового события и передать это уведомление для всех подключенных клиентов?
21 авг 19, 16:56    [21954640]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6498
Vadim Romanenko,

автор
и передать это уведомление для всех подключенных клиентов?

сразу в мозг? или другие варианты?
21 авг 19, 16:57    [21954643]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
invm
Member

Откуда: Москва
Сообщений: 8739
https://docs.microsoft.com/ru-ru/dotnet/framework/data/adonet/sql/query-notifications-in-sql-server
21 авг 19, 17:02    [21954647]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Minamoto
Member

Откуда: Москва
Сообщений: 1041
Vadim Romanenko
Как на стороне SQL Server можно сгенерировать некое уведомление о создании нового события и передать это уведомление для всех подключенных клиентов?

Для этого обычно используется трехзвенка, чтобы уведомления рассылал сервер приложений.
В двухзвенке на стороне WinForms-приложения делаете бесконечный пинг, который раз в N секунд/минут/часов вызывает ХП, проверяющую, нет ли для текущего пользователя новых уведомлений. Если есть - показывает.
21 авг 19, 17:04    [21954651]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
TaPaK
Vadim Romanenko,

автор
и передать это уведомление для всех подключенных клиентов?

сразу в мозг? или другие варианты?


Нет, пока чипы не вживляем, а прямая коммуникация тудой - вроде бы только на совести экстрасенсов :)

Под клиентами подразумевается клиентское приложение
21 авг 19, 17:08    [21954657]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Minamoto
Vadim Romanenko
Как на стороне SQL Server можно сгенерировать некое уведомление о создании нового события и передать это уведомление для всех подключенных клиентов?

Для этого обычно используется трехзвенка, чтобы уведомления рассылал сервер приложений.
В двухзвенке на стороне WinForms-приложения делаете бесконечный пинг, который раз в N секунд/минут/часов вызывает ХП, проверяющую, нет ли для текущего пользователя новых уведомлений. Если есть - показывает.


Да, я понимаю, что типичное решение - это трехзвенка. Но у нас - двухзвенка.
Бесконечный пинг - уверен, есть более экономичные решения.
21 авг 19, 17:09    [21954659]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 6698
Vadim Romanenko,

читайте по ссылке, которую привёл invm.
21 авг 19, 17:37    [21954695]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
andy st
Member

Откуда:
Сообщений: 753
Vadim Romanenko,
если нужны экономичные решения, то надо начать с описания того, что планируется экономить.
а в процессе написания окажется, что собсна предложенный бесконечный пинг техически мало чем отличается от других решений.
21 авг 19, 17:42    [21954700]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
andy st,

Возможно, Вы и правы. Чем городить вот этот весь огород с SQL Dependency...

Что есть. Компания, занимающаяся спецтранспортировкой людей. Поездки в день считаются в тысячах. Водители в сотнях. Операторов - десятки. Новая поездка может прийти кучей способов, в том числе через руки операторов. Оператор должен знать, если пришла новая поездка на сегодня в течении, ну, скажем, минуты.
21 авг 19, 18:20    [21954737]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Relic Hunter
Member

Откуда: AB
Сообщений: 7063
Vadim Romanenko
И вот - возникает вопрос. Как на стороне SQL Server можно сгенерировать некое уведомление о создании нового события и передать это уведомление для всех подключенных клиентов?
Взять в штат програмиста.
21 авг 19, 20:17    [21954813]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 6698
Vadim Romanenko,

сервер баз данных - вообще такая штука, которая отвечает на вопросы,но сама из не задаёт. Такова его природа. Это просто бочка с огурцами. Огурцы же в рот сами не запрыгивают? Хотя с галушками был прецедент.
Оповещать должен источник события, а не сервер, все остальное - это вандализм и надругательства.
21 авг 19, 21:53    [21954873]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 36379
Ставите любую очередь, пуляете в нее события с сервера, а клиенты пусть на очередь подписываются и разгребают.
21 авг 19, 22:09    [21954884]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Гавриленко Сергей Алексеевич
Ставите любую очередь, пуляете в нее события с сервера, а клиенты пусть на очередь подписываются и разгребают.

Смех в том, что у меня и так используется MSMQ. Но с одной стороны, это, вроде как, устаревшая штука. С другой стороны - я пока не вижу как пулять в MSMQ из хранимой процедуры SQL Server
22 авг 19, 18:24    [21955847]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
invm
https://docs.microsoft.com/ru-ru/dotnet/framework/data/adonet/sql/query-notifications-in-sql-server


Пробую реализовать подход SqlDependency. Но почему-то нотификация не приходит. Может кто-то сможет подсказать - почему?

В первую очередь подготовил БД
ALTER DATABASE MyDatabase SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE


При старте формы выполняется код:
        public frmMain()
        {
                ...
                test();
        }

        private void test()
        {
            AddSQL2Monitor("select [pk_id] from [dbo].[tbDispLeg]");
        }

        public void AddSQL2Monitor(String sqlRequest)
        {
            if (!CanRequestNotifications())
                throw new Exception("App has no SqlClientPermission -> Can't use SQL Dependency");
            AddDataMonitor(sqlRequest);
        }

        private bool CanRequestNotifications()
        {
            // In order to use the callback feature of the
            // SqlDependency, the application must have
            // the SqlClientPermission permission.
            try
            {
                SqlClientPermission perm =
                    new SqlClientPermission(
                    System.Security.Permissions.PermissionState.Unrestricted);

                perm.Demand();

                return true;
            }
            catch
            {
                return false;
            }
        }


Собственно, попытка добавления нотификации:
        private void AddDataMonitor(String sqlRequest)
        {
            if (connection == null)
            {
                connection = new SqlConnection(GetConnectionString());
            }
            if (connection.State != ConnectionState.Open) connection.Open();
            command = new SqlCommand(sqlRequest, connection);

            SqlDependency.Start(command.Connection.ConnectionString);
            command.Notification = null;
            new SqlDependency(command).OnChange += new OnChangeEventHandler(dependency_OnChange);
            DataTable table = new DataTable();
            using (SqlDataAdapter sqlDA = new SqlDataAdapter(command))
                sqlDA.Fill(table);
        }
    

        private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
        {
            command.Notification = null;
            new SqlDependency(command).OnChange += new OnChangeEventHandler(dependency_OnChange);
            DataTable table = new DataTable();
            using (SqlDataAdapter sqlDA = new SqlDataAdapter(command))
                sqlDA.Fill(table);
        }


Ни одного вызова dependency_OnChange не происходит. Как думаете - что не так?
22 авг 19, 20:21    [21955963]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29000
Vadim Romanenko
С другой стороны - я пока не вижу как пулять в MSMQ из хранимой процедуры SQL Server
Posting Message to MSMQ from SQL Server
22 авг 19, 20:36    [21955975]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
alexeyvg
Vadim Romanenko
С другой стороны - я пока не вижу как пулять в MSMQ из хранимой процедуры SQL Server
Posting Message to MSMQ from SQL Server


Да,спасибо, тоже уже нашел эту статью. Навскидку не завелась. Да и пока хочу попробовать через Dependency
Плюс пообщался с коллегами - вроде MSMQ имеет неприятные глюки. Время от времени. Когда очередь зависает и не пропускает сообщения через себя. Так что тут скорее нужно будет переводить проект уж сразу на другие очереди. Ну или может заведется Sql Dependency :)
22 авг 19, 20:40    [21955978]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
uaggster
Member

Откуда:
Сообщений: 688
alexeyvg
Vadim Romanenko
С другой стороны - я пока не вижу как пулять в MSMQ из хранимой процедуры SQL Server
Posting Message to MSMQ from SQL Server

Нуууу. Так не интересно.
В таком разе можно сразу CLR процедуру написать.
22 авг 19, 21:53    [21956037]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29000
uaggster
alexeyvg
пропущено...
Posting Message to MSMQ from SQL Server

Нуууу. Так не интересно.
В таком разе можно сразу CLR процедуру написать.
Ага, CLR ещё лучше, они как раз для таких задач.
22 авг 19, 22:26    [21956059]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Кто в курсе - можно ли как-то выдать гранты одновременно для любого юзера, который подключается через Windows Authentication? Для существующих и будущих юзеров? Возможно, есть какой-то подходящий псевдоним? А то что-то нотификации не приходят. И есть подозрение, что проблема в этом моменте:

support.microsoft.com
The user must have the correct client and server side permissions to request and receive notifications.
Users who execute commands requesting notification must have SUBSCRIBE QUERY NOTIFICATIONS database permission on the server.
26 авг 19, 16:49    [21957770]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29000
Vadim Romanenko
Кто в курсе - можно ли как-то выдать гранты одновременно для любого юзера, который подключается через Windows Authentication? Для существующих и будущих юзеров? Возможно, есть какой-то подходящий псевдоним? А то что-то нотификации не приходят. И есть подозрение, что проблема в этом моменте:

support.microsoft.com
The user must have the correct client and server side permissions to request and receive notifications.
Users who execute commands requesting notification must have SUBSCRIBE QUERY NOTIFICATIONS database permission on the server.
А "паблику" не подойдёт?
26 авг 19, 17:34    [21957793]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
alexeyvg,

Или не подошло, или этот SqlDependency вообще странно работает. Уже несколько раз перебрал и код, и документацию - единственное к чему можно прикопаться, это вот эти вот права для пользователя на сервере.
26 авг 19, 17:49    [21957811]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
Vadim Romanenko
Member

Откуда: Харьков, Украина
Сообщений: 1462
Все - я сдался. Не получилось никак. Возможно, кто-то сможет создать работающий прототип - было бы интересно увидеть пример приложения на каком-нибудь Гитхабе.

Реализовал через периодические async/await запросы за данными в таблице через, у которых ИД больше заданного. Количество данных в таблице меряется сотнями, так что не думаю чтоб оно сильно тупило.
26 авг 19, 18:38    [21957846]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29000
Vadim Romanenko
Реализовал через периодические async/await запросы за данными в таблице через, у которых ИД больше заданного. Количество данных в таблице меряется сотнями, так что не думаю чтоб оно сильно тупило.
Запрос чтения из очереди раз в полминуты от сотни операторов - это не слишком много...
Vadim Romanenko
alexeyvg,

Или не подошло, или этот SqlDependency вообще странно работает. Уже несколько раз перебрал и код, и документацию - единственное к чему можно прикопаться, это вот эти вот права для пользователя на сервере.
Так для пользователя, которому явно дали такие права (не через паблик, а ему самому), работает?

Vadim Romanenko
Возможно, кто-то сможет создать работающий прототип - было бы интересно увидеть пример приложения на каком-нибудь Гитхабе.
А пример кода от MS не подходит?
https://code.msdn.microsoft.com/How-to-use-SqlDependency-5c0da0b3
26 авг 19, 18:58    [21957862]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1032
Vadim Romanenko,

хотите некое альтернативное решение?

я правда не могу сказать как скажется такое решение на производительности сервера, это надо тестировать но руки не доходили.

данный подход основывается на функционале используемом в мониторах трасс и XE, а именно это процедура и функция:
sp_trace_getdata
fn_MSxe_read_event_stream


первая работает с серверными трассами, вторая с расширенными событиями, обе возвращают данные в виде потока.

также у нас есть средство позволяющее вызвать пользовательское событие:
sp_trace_generateevent

[ @eventid=] event_id Is the ID of the event to turn on. event_id is int, with no default. The ID must be one of the event numbers from 82 through 91, which represent user-defined events as set with sp_trace_setevent.

[ @userinfo= ] 'user_info' Is the optional user-defined string identifying the reason for the event. user_info is nvarchar(128), with a default of NULL.

[ @userdata= ] user_data Is the optional user-specified data for the event. user_data is varbinary(8000), with a default of NULL.



итого все что требуется в приложении:
 public static void Main(string[] args) {
    using (var cn = new SqlConnection("some_string")) {
       using (var cmd = new SqlCommand($"select [type], [data] from sys.fn_MSxe_read_event_stream('my_app', null);", cn) {
          try {
              cn.Open();
              var reader = cmd.ExecuteReader();
              while (reader.Read()) {
                  var somepayload = ParseData(reader.GetSqlBytes(1).ToSqlBinary().Value);
                  DoAction(somepayload);
              }
          }
          finnaly {}
       }
    }
 }

//остается только написать метод Parse которые будет парсить поток байт, там вполне все тривиально
//описание выходного потока для данных процедур можно найти в инете


на сервере:
create event session [my_app2] on server
add event user_event (where event_id = 90 or event_id = 91) --соответственно никто не мешает расширить фильтр скажем на user_info
go
alter event session [my_app] on server state = start;
go


в таком случае сможете отсылать уведомления в приложение без особых заморочек с service broker
при этом у вас есть возможность логировать уведомления можно для расширенных событий настроить цель в файл к примеру.
и на декларативном уровне у вас появляется некоторая возможность конфигурирования уведомлений в user_info можно передавать nvarchar(128) а в data varbinary(8000), а то как вы уже будете использовать эту информацию зависит от вас.

  exec [sp_trace_generateevent] 90, N'some event 1', null
  exec [sp_trace_generateevent] 91, N'some event 2', null


при обращении к функции fn_MSxe_read_event_stream запрос подключается к сиквелу в режиме чтения с типом ожидания XE_LIVE_TARGET_TVF, тоже самое делает студия когды вы щелкаете "наблюдать за данными предаваемыми в режиме реального времени"
26 авг 19, 19:22    [21957874]     Ответить | Цитировать Сообщить модератору
 Re: Уведомление клиентов об изменениях на сервере  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 29000
felix_ff
итого все что требуется в приложении
Так этот вариант ТС упоминал: "постоянный опрос сервера с каждого клиента"
А он хочет заменить опросы на вызовы клиента со стороны сервера при наступлении некоего события (что в теории правильно, хотя есть вопрос, стоит ли это такого геморроя).
26 авг 19, 22:08    [21957943]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить