上图代表我想要解决的方案。
根据我之前的经验,我知道进度报告模式可用于解决保持客户端更新的问题,但当时客户端正在直接与集线器通信,这意味着没有控制器或代码。
在上图中,问题是控制器需要先做东西才能调用DB。
此外,DB以文件的形式返回段,因此我添加了一个异步filesystemwatcher,用于在每次创建响应文件时通知我。
我们的目标是在收到响应段时继续向客户端浏览器提供响应段,直到我们到达响应结束时为止。
问题是:如何从控制器/服务方法触发signalR Hub并继续向客户端浏览器提供响应?
更新:
缩小问题范围
我的控制器调用服务方法
string contents = await _logService. ResponseFileWaiterAsync (myData.guid.ToString());
在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));
}
集线器报告对客户端的响应以及在完成之前查找下一个文件
public async Task UpdateResponseToClient(IProgress<string> progress,string filePath)
{
// Clients.Caller.appendReportToPage(ResponseHtml);
string result = await _jbaseLoggingService.ResponseFileWaiterAsync(filePath);
progress.Report(result);
}
问题:如何从服务方法/控制器触发进度报告中心? 完成更新后我应该在哪里完成我的请求 - 是否应该返回控制器?
答案 0 :(得分:0)
我想我可能已经解决了我的问题。我要做的第一件事就是渲染一个空占位符客户端,以便我可以启动客户端连接(集线器连接),然后在向控制器发送连接ID时对实际控制器方法进行AJAX调用。
控制器调用服务方法
await _logService.ResponseFileWaiterAsync(myData.guid.ToString(),clientId);
服务等待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 - 是客户端回调方法
MyResponseHub为空。我所需要的只是确保SignalR有一个中心来完成它的魔法
public class JbaseResponseHub : Hub
{
}
$(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#genproxy http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc