简体   繁体   English

Java:Azure 服务总线队列通过会话接收消息

[英]Java: Azure Service Bus Queue Receiving messsages with sessions

I'm writing code in java (using Azure SDK for Java), I have a Service bus queue that contains sessionful messages.我正在用 Java 编写代码(使用 Azure SDK for Java),我有一个包含会话消息的服务总线队列。 I want to receive those messages and process them to another place.我想接收这些消息并将它们处理到另一个地方。

I make a connection to the Queue by using QueueClient, and then I use registerSessionHandler to process through the messages (code below).我使用 QueueClient 连接到队列,然后使用 registerSessionHandler 处理消息(下面的代码)。

The problem is that whenever a message is received, I can print all details about it including the content, but it is printed 10 times and after each time it prints an Exception.问题是,每当收到一条消息时,我都可以打印有关它的所有详细信息,包括内容,但它会打印 10 次,每次打印后都会打印一个异常。 (printing 10 times: I understand that this is because there is a 10 times retry policy before it throws the message to the Dead letter queue and goes to the next message.) (打印 10 次:我理解这是因为在将消息抛出到死信队列并转到下一条消息之前有 10 次重试策略。)

The Exception says例外说

> USERCALLBACK-Receiver not created. Registering a MessageHandler creates a receiver.

The output with the Exception异常的输出

But I'm sure that the SessionHandler does the same thing as MessageHandler but includes support for sessions, so it should create a receiver since it receives messages.但我确信 SessionHandler 与 MessageHandler 做同样的事情,但包括对会话的支持,因此它应该创建一个接收器,因为它接收消息。 I have tried to use MessageHandler but it won't even work and stops the whole program because it doesn't support sessionful messages, and the ones I receive have sessions.我曾尝试使用 MessageHandler 但它甚至无法工作并停止整个程序,因为它不支持会话消息,而我收到的消息有会话。

My problem is understanding what the Exception wants me to do, and how can I fix the code so it won't give me any exceptions?我的问题是了解 Exception 想要我做什么,以及如何修复代码使其不会给我任何异常? Does anyone have suggestions on how to improve the code?有没有人有关于如何改进代码的建议? or other methods that do the same thing?或其他做同样事情的方法?

QueueClient qc = new QueueClient(
            new ConnectionStringBuilder(connectionString),
            ReceiveMode.PEEKLOCK);

qc.registerSessionHandler(
            new ISessionHandler() {
                @Override
                public CompletableFuture<Void> onMessageAsync(IMessageSession messageSession, IMessage message) {
                    System.out.printf(
                            "\nMessage received: " +
                                    "\n --> MessageId = %s " +
                                    "\n --> SessionId = %s" +
                                    "\n --> Content Type = %s" +
                                    "\n --> Content = \n\t\t %s",
                            message.getMessageId(),
                            messageSession.getSessionId(),
                            message.getContentType(),
                            getMessageContent(message)
                    );

                    return qc.completeAsync(message.getLockToken());
            }
                @Override
                public CompletableFuture<Void> OnCloseSessionAsync(IMessageSession iMessageSession) {
                    return CompletableFuture.completedFuture(null);
                }

                @Override
                public void notifyException(Throwable throwable, ExceptionPhase exceptionPhase) {
                    System.out.println("\n Exception " + exceptionPhase + "-" + throwable.getMessage());
                }
            },
            new SessionHandlerOptions(1, true, Duration.ofMinutes(1)),
            Executors.newSingleThreadExecutor()
);

(The getMessageContent(message) method is a separate method, for those interested:) (getMessageContent(message) 方法是一个单独的方法,对于那些有兴趣的人:)

public String getMessageContent(IMessage message){
    List<byte[]> content = message.getMessageBody().getBinaryData();
    StringBuilder sb = new StringBuilder();
    for (byte[] b : content) {
        sb.append(new String(b)
        );
    }
    return sb.toString();
}

For those who wonder, I managed to solve the problem!对于那些想知道的人,我设法解决了这个问题!

It was simply done by using Azure Functions ServiceBusQueueTrigger, it will then listen to the Service bus Queue and process the messages.它只是通过使用 Azure Functions ServiceBusQueueTrigger 完成的,然后它会监听服务总线队列并处理消息。 By setting isSessionsEnabled to true, it will accept sessionful messages as I wanted :)通过将 isSessionsEnabled 设置为 true,它将根据需要接受会话消息:)

So instead of writing more than 100 lines of code, the code looks like this now:所以现在代码看起来像这样,而不是写 100 多行代码:

public class Function {

@FunctionName("QueueFunction")
public void run(
        @ServiceBusQueueTrigger(
               name = "TriggerName", //Any name you choose
               queueName = "queueName", //QueueName from the portal
               connection = "ConnectionString", //ConnectionString from the portal
               isSessionsEnabled = true
        ) String message,
        ExecutionContext context
) {
    // Write the code you want to do with the message here
    // Using the variable messsage which contains the messageContent, messageId, sessionId etc.
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM