4

我正在尝试将 signalR 集线器作为使用 MEF 的插件的一部分。但是在 List<> 对象上调用 ImportMany 然后在 Global.asax 文件的 Application_Start() 方法中添加目录/容器/ComposeParts 部分后,我得到的是:

未捕获的类型错误:无法读取未定义的属性“服务器”。

我不知道问题是来自我的界面、插件、global.asax 文件还是 javascript。

界面:

public interface IPlugin
{

}

插件:

[Export(typeof(IPlugin))]
[HubName("testHub")]
public class TestHub : Hub, IPlugin
{
    public string Message()
    {
        return "Hello World!";
    }
}

在 Global.asax 文件中:

    [ImportMany(typeof (IPlugin))]
    private IEnumerable<IPlugin> _plugins { get; set; }

    protected void Application_Start()
    {
        var catalog = new AggregateCatalog();
        catalog.Catalogs.Add(new DirectoryCatalog(@"./Plugins"));
        var container = new CompositionContainer(catalog);
        container.ComposeParts(this);

        RouteTable.Routes.MapHubs();

        //log4net
        log4net.Config.XmlConfigurator.Configure();

        AreaRegistration.RegisterAllAreas();
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }

最后是javascript:

$(document).ready(function () {
        $.connection.hub.url = 'http://127.0.0.1/signalr/';
        var proxy = $.connection.testHub;
        $.connection.hub.start({ transport: ['webSockets', 'serverSentEvents', 'longPolling'] })
                   .done(function () {
                       proxy.invoke('Message').done(function(res) {
                           alert(res);
                       });
                   })
                   .fail(function () { alert("Could not Connect!"); });
    });

我发现的唯一信息是这篇文章,但我无法让它工作。当我手动添加引用时一切正常,但是当我在加载插件后查看“signalr/hubs”时,没有对我的集线器方法的引用。

非常感谢你的帮助。

4

1 回答 1

3

您的问题是 SignalR在第一次请求时缓存生成的“signalr/hubs”代理脚本。SignalR 提供缓存脚本以响应对“signalr/hubs”的每个后续请求。

SignalR 不仅缓存脚本本身,还缓存它在进程开始时找到的集线器集合。

您可以通过简单地不使用代理脚本来解决缓存的代理脚本问题,但这仍然无法让您实际连接到进程启动后加载的程序集中定义的集线器。

如果您希望能够连接到此类集线器,则需要实现自己的IHubDescriptorProvider,它知道在运行时加载的插件中定义的集线器。

您可以使用 SignalR 的DependencyResolver注册您的提供程序,它可以通过您传递给 MapSignalR 的HubConfiguration对象的Resolver属性传递给SignalR

也就是说,只要将插件添加到“./Plugins”目录,重新启动应用程序池/服务器进程可能会更容易。

于 2014-04-16T00:50:25.333 回答