簡體   English   中英

Java:Azure 服務總線隊列通過會話接收消息

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

我正在用 Java 編寫代碼(使用 Azure SDK for Java),我有一個包含會話消息的服務總線隊列。 我想接收這些消息並將它們處理到另一個地方。

我使用 QueueClient 連接到隊列,然后使用 registerSessionHandler 處理消息(下面的代碼)。

問題是,每當收到一條消息時,我都可以打印有關它的所有詳細信息,包括內容,但它會打印 10 次,每次打印后都會打印一個異常。 (打印 10 次:我理解這是因為在將消息拋出到死信隊列並轉到下一條消息之前有 10 次重試策略。)

例外說

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

異常的輸出

但我確信 SessionHandler 與 MessageHandler 做同樣的事情,但包括對會話的支持,因此它應該創建一個接收器,因為它接收消息。 我曾嘗試使用 MessageHandler 但它甚至無法工作並停止整個程序,因為它不支持會話消息,而我收到的消息有會話。

我的問題是了解 Exception 想要我做什么,以及如何修復代碼使其不會給我任何異常? 有沒有人有關於如何改進代碼的建議? 或其他做同樣事情的方法?

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()
);

(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();
}

對於那些想知道的人,我設法解決了這個問題!

它只是通過使用 Azure Functions ServiceBusQueueTrigger 完成的,然后它會監聽服務總線隊列並處理消息。 通過將 isSessionsEnabled 設置為 true,它將根據需要接受會話消息:)

所以現在代碼看起來像這樣,而不是寫 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