RegisterMessageHandlerが特定のトピック名で機能しないのはなぜですか?


9

以下で参照されている次のハンドラー(processMessageAsync)が特定のトピック名に対してトリガーされず、他のトピック名に対しては成功する理由がわかりません。

subscriptionClient.RegisterMessageHandler(processMessageAsync, msgOptions)

以下は私のSubscriberクラスです:

open System
open System.Linq
open System.Threading
open System.Text
open System.Threading.Tasks
open Microsoft.Azure.ServiceBus

type Subscriber(connectionString:string, topic:string, subscription:string) =

    let mutable subscriptionClient : SubscriptionClient = null

    let exceptionReceivedHandler (args:ExceptionReceivedEventArgs) =
        printfn "Got an exception: %A" args.Exception
        Task.CompletedTask

    let processMessageAsync (message:Message) (_:CancellationToken) = 

        try

            let _ = Encoding.UTF8.GetString(message.Body)
            subscriptionClient.CompleteAsync(message.SystemProperties.LockToken) |> Async.AwaitTask |> Async.RunSynchronously

            Task.CompletedTask

        with
            _ -> Task.CompletedTask

    member x.Listen() =

        async {

            subscriptionClient <- new SubscriptionClient(connectionString, topic, subscription)
            subscriptionClient.OperationTimeout <- TimeSpan.FromMinutes(3.0)

            let! rulesFound     = subscriptionClient.GetRulesAsync() |> Async.AwaitTask
            let  hasDefaultRule = rulesFound.Any(fun r -> r.Name = RuleDescription.DefaultRuleName)

            if hasDefaultRule then
                do! subscriptionClient.RemoveRuleAsync(RuleDescription.DefaultRuleName) |> Async.AwaitTask

            let msgOptions = MessageHandlerOptions(fun args -> exceptionReceivedHandler(args))
            msgOptions.AutoComplete         <- false
            msgOptions.MaxAutoRenewDuration <- TimeSpan.FromMinutes(1.0)
            msgOptions.MaxConcurrentCalls   <- 1

            subscriptionClient.RegisterMessageHandler(processMessageAsync, msgOptions)
        }

    member x.CloseAsync() =

        async {

            do! subscriptionClient.CloseAsync() |> Async.AwaitTask
        }

サブスクライバーを実行する方法は次のとおりです。

open System
open Subscription.Console

let connectionString = <connection_string>

[<EntryPoint>]
let main argv =

    printfn "Welcome to Subscription.Console"

    let topic,subscription = "Topic.courier-accepted","Subscription.all-messages"
    let subscriber = Subscriber(connectionString, topic, subscription)

    async { do! subscriber.Listen()
          } |> Async.RunSynchronously

    Console.ReadKey() |> ignore

    async { do! subscriber.CloseAsync()
          } |> Async.RunSynchronously

    0 // return an integer exit code 

次のコードは、私のサブスクライバーが受信する必要がある(ただし、受信しない)メッセージをパブリッシュします。

[<Fact>]
let ``Publish courier-accepted to servicebus``() =

    async {

        // Setup
        let  client    = TopicClient(sbConnectionstring, "Topic.courier-accepted")
        let! requestId = requestId()

        let updated = requestId |> modifyRequestId someCourierResponse
        let json    = JsonConvert.SerializeObject(updated)
        let message = Message(Encoding.UTF8.GetBytes(json))

        message.Label <- sprintf "request-id(%s)" (requestId.ToString())

        // Test
        do! client.SendAsync(message) |> Async.AwaitTask

        // Teardown
        do! client.CloseAsync()       |> Async.AwaitTask
    }

注意:

上記のコードの興味深い点は、ServiceBusTriggerを同じトピックとサブスクリプション名に設定してAzure関数を実行すると、テストを実行するたびにそのAzure関数がトリガーされることです。

  • 例外メッセージが表示されない
  • exceptionReceivedHandler関数がSubscriberインスタンスでトリガーされない
  • ServicebusリソースのAzureダッシュボードでユーザーエラーを確認していません

異なるトピック名で成功する

トピック名を「courier-requested」に変更すると、サブスクライバーインスタンスがメッセージを受信します。

[<Fact>]
let ``Publish courier-requested to servicebus topic``() =

    // Setup
    let client    = TopicClient(sbConnectionstring, "Topic.courier-requested")
    let message   = Message(Encoding.UTF8.GetBytes(JsonFor.courierRequest))
    message.Label <- sprintf "courier-id(%s)" "b965f552-31a4-4644-a9c6-d86dd45314c4"

    // Test
    async {

        do! client.SendAsync(message) |> Async.AwaitTask
        do! client.CloseAsync()       |> Async.AwaitTask
    }

トピック名が調整されているサブスクリプションは次のとおりです。

[<EntryPoint>]
let main argv =

    printfn "Welcome to Subscription.Console"

    let topic,subscription = "Topic.courier-requested","Subscription.all-messages"
    let subscriber = Subscriber(connectionString, topic, subscription)

    async { do! subscriber.Listen()
          } |> Async.RunSynchronously

    Console.ReadKey() |> ignore

    async { do! subscriber.CloseAsync()
          } |> Async.RunSynchronously

    0 // return an integer exit code

これが、Azureポータルの2つのトピックです。 ここに画像の説明を入力してください

ポータルでトピックをクリックすると、結果が異なります。

定期購入を表示するためだけに[宅配便で承認]をクリックする必要があることに気付きました。ただし、[宅配便リクエスト済み]を1回クリックすると、そのサブスクリプションをすぐに表示できます。


1
I don't receive any exception messages、おそらくあなたが例外を飲み込んでいるからですか?1つwith _後にブロックが表示されるtry
user1623521

宅配便で承認されたトピックの追加サブスクリプションを作成し、ポータルに登録したサブスクリプション値と一致するサブスクリプション値でサブスクライバーを起動し、サブスクライバーがまだ実行されている間に最近作成したサブスクリプションを削除した後、例外が発生しました。
スコットニムロッド

私の側では問題を再現できません。ServiceBusポータルで異常な動作に遭遇したようです。SBチームにサポートチケットを送信できます。
Jay Gong

昨日チケットを提出しました。
スコットニムロッド

回答:


0

問題のあるトピックを削除して再作成しようとしたことを正しく理解していれば、Azureの問題のように思えます。上記の動作を2回クリックする必要がある場合は、取得しないでください。時々、Azureで作成したことがありますが、インフラストラクチャの下流のどこかに問題があり、それを解決するにはサポートリクエストが唯一の方法です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.