17

我正在使用 SignalR 2,但我无法弄清楚如何使用我的 Hub 方法,例如从控制器操作内部。

我知道我可以做到以下几点:

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

但这会直接在客户端执行该方法。

如果我的服务器端ClientSideMethod(param)方法中有业务逻辑,我想从控制器调用与从客户端调用它时相同的方式怎么办?

目前我public static void ClientSideMethod(param)在我的集​​线器内使用,在这种方法中我使用IHubContext来自ConnectionManager.

这样做没有更好的办法吗?

以下不起作用(在 SignalR 2 中不再起作用?):

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

访问客户端时,出现“不支持通过集线器管道创建集线器”异常。

4

2 回答 2

13

可能会创建一个“帮助器”类来实现您的业务规则并由您的集线器和控制器调用:

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);
    }
}
于 2013-07-27T12:07:32.633 回答
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();
}
于 2014-08-13T13:31:12.937 回答