2016-05-14 71 views
0

我似乎有一个问题,从使用SignalR的控制器动作发送警报(Toast)消息。除非在发送呼叫后添加Thread.Sleep(),否则我从不会看到该消息。不可避免地,发送呼叫发生在return View()之前,因此我想像一下,在前一个视图中,警报在毫秒内可见,直到新的视图被服务。从控制器动作发送SignalR警报消息

我的第一个粗略的解决方案是使用计时器继续发送消息,直到得到确认。

该解决方案很臭。我还可以做些什么?我可以让'接收'页面轮询服务器,看看它们是否有任何警报,但是这打破了SignalR的目的。

但是,然后,也许SignalR不适合我的情况,我应该只发送警报作为模型上的JSON字符串。

Login行动:

.... 
//ModelState.AddModelError("", "Invalid login attempt."); 
AlertsHub.ShowClientAlert(new Alert(AlertLevel.Error, "Invalid login attempt.")); 
return View(model); 

集线器:

public class AlertsHub : Hub 
{ 
    private static Alert pendingAlert; 
    static Timer pollTimer; 

    internal static void ShowClientAlert(Alert alert) 
    { 
     if (pendingAlert != null) 
     { 
      return; 
     } 
     pendingAlert = alert; 
     pollTimer = new Timer(_ => SendAlert(pendingAlert), null, 0, 500); 
    } 

    static private void SendAlert(Alert alert) 
    { 
     IHubContext context = GlobalHost.ConnectionManager.GetHubContext<AlertsHub>(); 
     context.Clients.All.ShowAlert(alert.Level.ToString(), alert.Message, alert.Title); 
    } 

    [HubMethodName("AlertReceived")] 
    public void AlertReceived(Guid alertId) 
    { 
     pollTimer.Dispose(); 
     pendingAlert = null; 
    } 
} 

从JS:

var toast; 

$(function() { 
    if (typeof toast != 'undefined' && toast != null) { 
     showToast(toast); 
     toast = null; 
    } 

    var alertsProxy = $.connection.alertsHub; 

    alertsProxy.client.showAlert = function(alertId, level, message, title) { 
     toast.alertId = alertId; 
     toast.level = level; 
     toast.message = message; 
     toast.title = title; 
    }; 

    $.connection.hub.start() 
     .done(function() { 
      console.log('Now connected, connection ID=' + $.connection.hub.id); 
     }) 
     .fail(function() { 
      console.log('Could not Connect!'); 
     }); 
}); 

function showToast(toast) { 
    switch (toast.level.toLowerCase()) { 
    case "success": 
     toastr.success(toast.message, toast.title); 
     break; 
    ... 
    } 

    alertsProxy.server.AlertReceived(alertId) 
     .done(function() { 
      console.log("Alert '" + alertId + "' acknowledged."); 
     }) 
     .fail(function() { 
      console.log("Acknowledgement of alert '" + alertId + "' failed."); 
     }); 
} 
+0

你能分享一下相关的代码吗? (Controller + JS,如果两者兼有) –

+0

@ PedroG.Dias目前代码处于一种不稳定的状态,但我只会展示我正在进行的实验性工作。它仍然需要很多工作。 – ProfK

回答