将WebJobs与Azure Service Bus和Sessions一起使用

时间:2015-10-06 11:28:00

标签: c# session azureservicebus azure-webjobs azure-servicebus-queues

我是Azure服务总线的新手,正在使用Azure SDK和Visual Studio 2013的Service Bus Queues,WebJobs,v2.5进行概念验证

从总线排队和排队消息非常简单,但为了实现请求 - 响应模式,我看起来需要使用会话,这就是轮子脱落的地方。

这是WebJobs项目的概念验证代码。它要求您创建两个服务总线队列: test-request test-response 。响应队列必须具有启用会话=真

class Program
{
    private static string _azureServiceBusConnection;

    static void Main()
    {
        _azureServiceBusConnection = ConfigurationManager.ConnectionStrings["AzureWebJobsServiceBus"].ConnectionString;

        var host = new JobHost();
        Task.Factory.StartNew(() => Run());

        try
        {
            host.RunAndBlock();
        }
        catch (Exception ex)
        {
            Console.WriteLine("RunAndBlock() Unexpected {0}: {1}", ex.GetType().FullName, ex.Message);  
            throw;
        }
    }

    private static async Task Run()
    {
        await Task.Delay(1000);

        var request = QueueClient.CreateFromConnectionString(_azureServiceBusConnection, "test-request");
        var response = QueueClient.CreateFromConnectionString(_azureServiceBusConnection, "test-response");

        var sessionid = Guid.NewGuid().ToString();
        MessageSession receiver;
        try
        {
            receiver = response.AcceptMessageSession(sessionid);
        }
        catch (Exception ex )
        {
            Console.WriteLine("AcceptMessageSession() Unexpected {0}: {1}", ex.GetType().FullName, ex.Message);
            throw;
        }

        var payload = new RequestModel {ID = Guid.NewGuid(), Delay = 1};
        var message = new BrokeredMessage(payload) {ReplyToSessionId = sessionid};
        try
        {
            request.Send(message);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Send() Unexpected {0}: {1}", ex.GetType().FullName, ex.Message);
            throw;
        }

        var receivedMessage = receiver.Receive(TimeSpan.FromSeconds(5));
        if (receivedMessage != null)
        {
            // Request processed within the timeout period
            var responseBody = receivedMessage.GetBody<RequestModel>();
            Console.WriteLine("Inline response to {0}", responseBody.ID );
            receivedMessage.Complete();
        }
        else
        {
            // Request processing timed out - should be handled by LocalResponseQueue WebJob (see below)
            Console.WriteLine("ERROR: Response timed out.");
        } 
    }
}

public class RequestModel
{
    public Guid ID { get; set; }
    public int Delay { get; set; }
}

public class RemoteSystemRequestQueue
{
    // Simulates the processing of the request on a remote system
    public static void ProcessQueueMessage([ServiceBusTrigger("test-request")] BrokeredMessage request, [ServiceBus("test-response")] out BrokeredMessage response)
    {
        // Wait for the prescribed delay, then bounce the request payload back via the response queue
        var requestBody = request.GetBody<RequestModel>();
        Console.WriteLine("Recieved Request {0}, delay={1}", requestBody.ID, requestBody.Delay);
        Task.Delay(requestBody.Delay * 1000).Wait();
        response = new BrokeredMessage(requestBody) {SessionId = request.ReplyToSessionId};
        request.Complete();
        Console.WriteLine("Completed Request {0}, delay={1}", requestBody.ID, requestBody.Delay);
    }
}

public class LocalResponseQueue
{
    // Should be called ONLY when the processing took longer than the timeout
    public static void ProcessQueueMessage([ServiceBusTrigger("test-response")] BrokeredMessage message, TextWriter logger)
    {
        var msgBody = message.GetBody<RequestModel>();
        Console.WriteLine("ResponseFactory Recieved Reply {0}", msgBody.ID);
    }
}

在测试响应队列上启用Sessions = true 时,对 host.RunAndBlock()的调用会抛出带有消息的System.InvalidOperationException

要求会话的实体无法创建非会话消息接收器

输出如下:

Found the following functions:
ServiceBusPoc.RemoteSystemRequestQueue.ProcessQueueMessage
ServiceBusPoc.LocalResponseQueue.ProcessQueueMessage
Executing: 'RemoteSystemRequestQueue.ProcessQueueMessage' because New service bus message detected on 'test-request'.
Recieved Request 4f000f8f-dd69-4909-9ec4-020fec12366c, delay=1
RunAndBlock() Unexpected System.InvalidOperationException: It is not possible for an entity that requires sessions to create a non-sessionful message receiver.
TrackingId:7836ac90-6920-4e6c-b7f1-cf648e2a17e5_G38_B10,TimeStamp:10/6/2015 12:37:05 PM

请注意,在RemoteSystemRequestQueue对象完成处理排队请求之前抛出异常

我认为这意味着WebJobs无法处理会话(至少以我使用它们的方式)

任何人都可以对此有所了解,或者我将不得不放弃WebJobs?

1 个答案:

答案 0 :(得分:0)

您使用的是哪个版本的WebJobs SDK?在我们当前的v1.1.0版本(仍然是预发行版)中,我们已经开始为ServiceBus配置开辟更多选项。参见:

您现在基本上可以控制以前隐藏在SDK内部的更多消息传递详细信息。但是,关于完整的会话支持,我们确实有this open issue可能更接近您的方案。如果是这样,如果您无法使用上述内容,请将您的方案详细信息添加到该问题中。感谢。