Как заставить приложение ASP.NET MVC читать из очереди служебной шины Azure?

У меня есть рабочая роль, работающая в Windows Azure, которая генерирует сообщения. У меня есть приложение ASP.NET MVC с концентратором SignalR. Я хотел бы отправлять сообщения из рабочей роли в концентратор SignalR, который затем будет отправлять их подключенным клиентам в режиме реального времени. Мои мысли заключаются в том, чтобы использовать очередь служебной шины Azure, из которой будет считывать приложение ASP.NET MVC. Все это кажется достаточно простой концепцией, но я не уверен, как подключить служебную шину QueueClient в приложении MVC. Я могу найти множество примеров с ASP.NET MVC, помещающих сообщения в очередь, чтобы их забрала служба рабочей роли, но не наоборот.

Вопрос: есть ли способ сделать это? Может ли кто-нибудь указать мне направление некоторых образцов и т.д.?


person jcaddy    schedule 13.01.2014    source источник


Ответы (2)


В нашем проекте мы используем это в MvcApplication> Application_Start:

new Thread(t => Container.Resolve<IMessageRouter>().StartRouting()).Start();

Мы также используем DI (контейнер Windsor), маршрутизатор зарегистрирован как Transient. Маршрутизатор запускается с веб-приложением в параллельном потоке и работает постоянно.

Маршрутизатор имеет контекст подключения концентратора SignalR и прослушиватель темы (оболочка клиента темы):

public class MessageRouter : IMessageRouter
{
    private string _subscriptionName = "Subscription_0";

    private IHubConnectionContext ClientContext
    {
        get { return GlobalHost.ConnectionManager.GetHubContext<MessageHub>().Clients; }
    }

    private RoleInstance CurrentRoleInstance
    {
        get // try to get current Azure role instance
        {
            if (RoleEnvironment.IsAvailable && RoleEnvironment.CurrentRoleInstance != null)
            {
                return Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.CurrentRoleInstance;
            }

            return null; // return null if not Azure environment
        }
    }

    private string TopicName
    {
        get { return ConfigurationHelper.TopicName; }
    }

    private string TopicConnectionString
    {
        get { return ConfigurationHelper.TopicConnectionString; }
    }

    public ITopicListener TopicListener { get; set; }

    public void OnMessage(QueueMessage message)
    {
        ClientContext.Group(message.GetRecipientGroup()).updateProgress(message.GetBody<string>());
    }

    public void StartRouting()
    {
        TopicListener.Bind(TopicConnectionString, TopicName, _subscriptionName).StartListening(OnMessage);
    }

    public MessageRouter()
    {
        if (CurrentRoleInstance != null) // check Azure environment is exist
        {
            int instanceIndex = 0; string instanceId = CurrentRoleInstance.Id;

            if (!int.TryParse(instanceId.Substring(instanceId.LastIndexOf(".") + 1), out instanceIndex)) // on cloud
            {
                int.TryParse(instanceId.Substring(instanceId.LastIndexOf("_") + 1), out instanceIndex); // on compute emulator
            }

            _subscriptionName = String.Format("{0}_{1}", CurrentRoleInstance.Role.Name, instanceIndex);
        }
    }
}

И это работает. Надеюсь это поможет.

person Kirill Karahainko    schedule 14.01.2014
comment
Именно то, что я искал - большое спасибо и очень признателен. Вполне законно запускать еще один поток в таком приложении MVC? И я вижу, что вы получаете контекст клиента так же, как @viperguynaz, предложенный, глядя на шаблон вещания сервера. Также интересует публикация Брэди Гастера (хотя, возможно, заменено), где он внедряет клиент очереди sb в концентратор SignalR. Спасибо за помощь. - person jcaddy; 15.01.2014
comment
Я знаю, что это старый пост, но не могли бы вы предоставить больше информации о том, что такое ITopicListener? Поиск в Google, кажется, возвращает кучу несвязанных результатов. - person anon; 23.09.2020

Прочтите «Как получать сообщения из очереди» в http://www.windowsazure.com/en-us/documentation/articles/service-bus-dotnet-how-to-use-queues/

Но если у вас есть рабочая роль, генерирующая сообщения, и вы хотите использовать SignalR, я бы рекомендовал использовать эту рабочую роль в качестве широковещательного центра для SignalR — см. Учебник: трансляция сервера с помощью SignalR 2.0

person viperguynaz    schedule 13.01.2014
comment
Спасибо за это. Я должен был, вероятно, сказать больше в своем посте. Рабочая роль недоступна для клиента — она находится в виртуальной сети Azure. Поэтому мне нужно отправить сообщение в концентратор SignalR. Теперь я мог бы создать клиент очереди служебной шины, но он должен сохраняться за пределами вызовов концентратора, которые являются временными. Поэтому мне нужно, чтобы компонент работал «все время» на сайте ASP.NET, на котором размещены концентраторы SignalR. Может есть способ раскрутить какой-нибудь клиент очереди на AppStart - WebActivator? - а затем внедрить его в хаб-классы с помощью DI??!! Любые идеи? - person jcaddy; 14.01.2014