2016-05-14 72 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

回答