Прогресс SignalR через контроллер MVC

Сценарий рабочего процесса

Выше изображение представляет сценарий, который я пытаюсь решить.

Из моего предыдущего опыта я знаю, что шаблон отчетов Progress можно использовать для решения проблемы обновления клиента, но тогда клиент напрямую связывался с концентратором, то есть за ним не было ни контроллера, ни кода.

На изображении выше проблема заключается в том, что контроллеру нужно что-то сделать, прежде чем он сможет выполнить вызов в БД.

Кроме того, БД возвращает сегменты в форме файлов, поэтому я добавил асинхронный файловый системный наблюдатель для уведомления каждый раз, когда создается файл ответов.

Цель состоит в том, чтобы поддерживать клиентский браузер сегментами ответов, как при их получении, до тех пор, пока мы не достигнем конца ответов.

Вопрос заключается в следующем: как я запускаю сигнальный хаб из методов контроллера / службы и продолжаю передавать ответы в браузер клиента?

ОБНОВИТЬ:

Чтобы сузить проблему

  1. Мой контроллер вызывает метод обслуживания

    string contents = await    _logService. ResponseFileWaiterAsync         (myData.guid.ToString());
    
  2. в ResponseFilewaiterAsync метод, когда создается первый файл, я запускаю концентратор

     BroadcastResponseToClient(responseFilePath, hubConnection);
    
         private void BroadcastResponseToClient(string responseFilePath, HubConnection hubConnection)
        {
            var hub = hubConnection.CreateHubProxy(typeof(string).Name);
            hubConnection
                .Start()
                .ContinueWith(_ => hub.Invoke("UpdateResponseToClient", ResponseHtml));
        }
    
  3. Концентратор сообщает об ответах клиенту, а также ищет следующий файл до тех пор, пока это не будет сделано

           public async Task UpdateResponseToClient(IProgress<string> progress,string filePath)
        {
            // Clients.Caller.appendReportToPage(ResponseHtml);
    
           string result = await _jbaseLoggingService.ResponseFileWaiterAsync(filePath);
            progress.Report(result);
        }
    

Проблема: как запустить концентратор отчетов о ходе выполнения из сервисного метода / контроллера? Где я должен выполнить свой запрос, когда он будет сделан с обновлениями - должен ли он вернуться к контроллеру?

1 ответ

Решение

Я думаю, что, возможно, решил свою проблему. Первое, что мне нужно было сделать, - визуализировать пустого клиента-заполнителя, чтобы я мог запустить свое клиентское соединение (концентраторное соединение), а затем сделать AJAX-вызов фактического метода контроллера при отправке идентификатора соединения в контроллер.

  1. Контроллер вызывает сервисный метод

    await  _logService.ResponseFileWaiterAsync(myData.guid.ToString(),clientId);
    
  2. Служба ожидает, пока filewatcher уведомит о созданном / переименованном файле, затем прочитает содержимое файла и сообщит его клиенту с помощью clientId

     ResponseFileWaiterAsync(string responseFileName, string clientId)
     {
        //do stuff
        await DropFileHelper.WaitForResponseFileAsync(responseFilePath);
        contents = LoadResponseFile(responseFilePath);
        //do stuff
        Clients.Client(clientId).appendReportToPage(contents);
     }
    

Клиенты загружаются в конструктор, используя

Clients = GlobalHost.ConnectionManager.GetHubContext<MyResponseHub>().Clients;

appendReportToPage - метод обратного вызова клиента

  1. MyResponseHub пуст. Все, что мне было нужно, это убедиться, что у SignalR есть концентратор для работы через магию

                          public class JbaseResponseHub : Hub
                            {
                            }
    
    1. JS на стороне клиента

   $(function () {                   
        var _clientId;
        var hubProxy = $.connection.myResponseHub;        
        hubProxy.client.appendReportToPage = function (ResponseHtml) {
            // Add the message to the page.                 
            $('#responseBody').append( "<p>"+ResponseHtml+"</p>" + '</br></br></br>');
        };

        $.connection.hub.start()
            .done(function () {
                //alert('in hub start');
                _clientId = $.connection.hub.id;
                console.log('Now connected, connection ID=' + $.connection.hub.id);
                //alert(_clientId);

                $.ajax({
                    type: 'GET',
                    url: '/mycontroller/ProcessRequest',
                    data: { qs: $('#encryptedString').html().trim(), clientId: _clientId },
                    cache: false,
                    success: function (result) {
                        
                    }
                });
            })
            .fail(function(){ console.log('Could not Connect!'); });

});

Уроки выучены

  • Клиент должен быть обработан так, чтобы он мог создать соединение с концентратором
  • Вы можете общаться с клиентами из класса обслуживания / методов, если у вас есть доступ к клиентам

Полезные ссылки

http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc

Другие вопросы по тегам