2013-07-27 44 views
15

我正在使用SignalR 2,我無法弄清楚如何使用我的Hub方法,例如從控制器動作中。使用控制器的Hub方法?

我知道我能做到以下幾點:

var hub = GlobalHost.ConnectionManager.GetHubContext<T>(); 
hub.Clients.All.clientSideMethod(param); 

但是,直接執行該方法在客戶端。

如果我的服務器端有業務邏輯怎麼辦ClientSideMethod(param)方法我想從我的控制器調用與從客戶端調用時相同的方式?

目前我在我的集​​線器內使用public static void ClientSideMethod(param),在該方法中,我使用ConnectionManager中的IHubContext

難道沒有更好的做法嗎?

下不工作(在SignalR 2了嗎?):

var hubManager = new DefaultHubManager(GlobalHost.DependencyResolver); 
instance = hubManager.ResolveHub(typeof(T).Name) as T; 
instance.ClientSideMethod(param); 

在那裏,我得到一個訪問客戶時例外,「集線器不通過集線器管道不支持創建」。

+0

爲什麼不從客戶端,我以爲是JS做到這一點,你可以做一個Ajax請求,你需要在控制器 – MEYWD

+1

@MEYWD什麼:因爲例如我有一個管理界面,我想在「發生什麼事情」時更新。例如。客戶端訪問特定的頁面,所以我想從該頁面觸發控制器操作中的hub方法。實際的客戶不關心這一點,那他爲什麼要發佈這個消息呢? – ChrFin

+0

我已經做了類似的事情,我有客戶端和管理員(特殊客戶端),管理員發送命令並等待客戶端的響應,爲此我做了一個管理員列表和客戶端列表,管理員選擇一個客戶端,保留它,以便其他管理員不使用它,然後發送一個命令,集線器將其中繼到客戶端,客戶端將響應返回到集線器,作爲回報,該響應被中繼到管理員並且響應打印在屏幕 – MEYWD

回答

11

,因爲我沒有找到一個「很好的解決方案:」我正在使用@ michael.rp的一些改進方案:

我確實創造了以下基本類:

public abstract class Hub<T> : Hub where T : Hub 
{ 
    private static IHubContext hubContext; 
    /// <summary>Gets the hub context.</summary> 
    /// <value>The hub context.</value> 
    public static IHubContext HubContext 
    { 
     get 
     { 
      if (hubContext == null) 
       hubContext = GlobalHost.ConnectionManager.GetHubContext<T>(); 
      return hubContext; 
     } 
    } 
} 

然後我在實際的集線器(例如, public class AdminHub : Hub<AdminHub>)我有(靜態)方法如下所示:

/// <summary>Tells the clients that some item has changed.</summary> 
public async Task ItemHasChangedFromClient() 
{ 
    await ItemHasChangedAsync().ConfigureAwait(false); 
} 
/// <summary>Tells the clients that some item has changed.</summary> 
public static async Task ItemHasChangedAsync() 
{ 
    // my custom logic 
    await HubContext.Clients.All.itemHasChanged(); 
} 
11

威力工作,以創建實現業務規則,並通過集線器和你的控制器都被稱爲一個「助手」類:

public class MyHub : Hub 
{ 
    public void DoSomething() 
    { 
     var helper = new HubHelper(this); 
     helper.DoStuff("hub stuff"); 
    } 
} 

public class MyController : Controller 
{ 
    public ActionResult Something() 
    { 
     var hub = GlobalHost.ConnectionManager.GetHubContext<MyHub>(); 
     var helper = new HubHelper(hub); 
     helper.DoStuff("controller stuff"); 
    } 
} 

public class HubHelper 
{ 
    private IHubConnectionContext hub; 

    public HubHelper(IHubConnectionContext hub) 
    { 
     this.hub = hub; 
    } 

    public DoStuff(string param) 
    { 
     //business rules ... 

     hub.Clients.All.clientSideMethod(param); 
    } 
} 
+0

+1,因爲它已經是一個更好的方法,然後我的,但我仍然希望可以使用Hub方法「直接」,因爲它似乎「更清晰」和「更容易理解」給我... – ChrFin

+0

@ChrFin你有沒有找到一種方法從程序集內成功調用集線器方法?如果無法調用集線器的實例,則此選項似乎是最乾燥和最劃分的。 –

+0

@BrandonWittwer:不,不是。我只是沒有將答案標記爲接受,因爲我仍然希望得到「本地解決方案」。我會在我目前的解決方案中添加一個答案... – ChrFin