Концентраторы карт в проекте, на который делается ссылка - программирование
Подтвердить что ты не робот

Концентраторы карт в проекте, на который делается ссылка

http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-signalr-20-self-host

В моем случае мои концентраторы находятся в проекте, на который ссылается код проекта, который закручивает самообслуживаемое приложение.

В строке connection.Start().Wait(); появляется исключение. Ниже приведена последовательность исключений, выделенных в этой строке:

  • Указанный раздел реестра не существует System.IO.IOException
  • Консоль MessageHub не может быть разрешена InvalidOperationException
  • Удаленный сервер ответил на ошибку: (500) Внутренняя ошибка сервера Веб-исключение

Подпись класса концентратора сообщений в указанном проекте public class MessageHub : Hub.

Обновление:. Чтобы проверить теорию, я переместил класс концентратора из ссылочного проекта в свой тестовый проект и обновил пространство имен. Это сработало. Поэтому я думаю, что теория здесь звучит... default hub resolution не находит концентраторы в проекте, на который делается ссылка, или в отдельном пространстве имен.

Как я могу убедить MapHubs найти тестовый концентратор в проекте, на который ссылается?

4b9b3361

Ответ 1

Я думаю, что нашел ответ на этот вопрос.

После некоторого копирования вокруг исходного кода, похоже, что SignalR использует следующий метод, чтобы назначить IAssemblyLocator для поиска концентраторов.

    internal static RouteBase MapHubs(this RouteCollection routes, string name, string path, HubConfiguration configuration, Action<IAppBuilder> build)
    {
        var locator = new Lazy<IAssemblyLocator>(() => new BuildManagerAssemblyLocator());
        configuration.Resolver.Register(typeof(IAssemblyLocator), () => locator.Value);

        InitializeProtectedData(configuration);

        return routes.MapOwinPath(name, path, map =>
        {
            build(map);
            map.MapHubs(String.Empty, configuration);
        });
    }

public class BuildManagerAssemblyLocator : DefaultAssemblyLocator
{
    public override IList<Assembly> GetAssemblies()
    {
        return BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList();
    }
}

public class DefaultAssemblyLocator : IAssemblyLocator
{
    public virtual IList<Assembly> GetAssemblies()
    {
        return AppDomain.CurrentDomain.GetAssemblies();
    }
}

Это заставило меня попытаться просто добавить мою внешнюю сборку в текущий домен, потому что, хотя на нее ссылались, она не была загружена.

Поэтому перед вызовом WebApp.Start я вызываю следующую строку.

    static void Main(string[] args)
    {
        string url = "http://localhost:8080";

        // Add this line
        AppDomain.CurrentDomain.Load(typeof(Core.Chat).Assembly.FullName);

        using (WebApp.Start<Startup>(url))
        {
            Console.WriteLine("Server running on {0}", url);
            Console.ReadLine();
        }
    }

Где Core.Chat - это просто класс Hub, который я использую. И затем загружаются концентраторы, определенные в ссылочной сборке.

Там может быть более прямой путь, но я ничего не могу найти в документации.

Надеюсь, что это поможет.