EasyNetQ Ожидание события от ISubscriptionResult - PullRequest
1 голос
/ 02 июля 2019

Я использую EasyNetQ для управления моей шиной обмена сообщениями RabbitMq, используя f #, а это довольно просто, этот публикует сообщения:

let HandleBusResponse (data:BaseFrame) (bus:IBus) : ISubscriptionResult = 
    let handler = Action<RequestMessage>(fun request ->
        let cabinetSubscribeId = sprintf "Project.%i" request.ProjectId
            match request.FrameType with 
                  | FrameType.UNDEFINED -> 
                    let response = ResponseService.BusRequestFactory request data
                  | _ -> 
                    let response = ResponseService.BusRequestFactory request data 
    bus.Publish<ResponseMessage>(response, cabinetSubscribeId))

И этот метод (подписчик) вызывается где-то в приложении, как:

HandleBusResponse data bus
//WAIT FOR MESSAGE ARRIVAL
informationPools.AddToConnectionPool(data.ProjectId, client) |> ignore 
ClientInfoHandler client data |> Async.RunSynchronously|> ignore 

В основном так же, как это работает в c #.

Теперь этот код не обработчик подписчика, мой вопрос, возможно ли обнаружить из этой части

// ПОДОЖДИТЕ ДЛЯ ПОЛУЧЕНИЯ СООБЩЕНИЯ

, используя какое-то время, если появилось что-то новое (помня, что второй фрагмент кода находится вне обработчика подписки)?

1 Ответ

1 голос
/ 03 июля 2019

Если бы вы могли опубликовать полный минимальный пример, скомпилированный и работающий в F # Interactive, было бы проще напрямую реализовать решение для вашей проблемы. Однако одно из решений, которое должно работать в целом, - это ожидание событий. В F # вы можете создавать такие события:

let requestArrived = Event<RequestMessage>()
let responsePublished = Event<ResponseMessage>()

Затем вы можете асинхронно ожидать эти события и обрабатывать данные, которые они генерируют:

let rec messageLoop<'message> f (event: IEvent<'message>) = 
    async {
        let! message = event |> Async.AwaitEvent 
        message |> f
        return! messageLoop f event
    }

Итак, в вашем // WAIT FOR MESSAGE ARRIVAL блоке вы можете сделать что-то подобное (в зависимости от того, хотите ли вы обрабатывать запросы или ответы или что вы хотите с ними делать:

requestArrived.Publish |> messageLoop (fun request -> printfn "Received Request: %A" request)
// AND/OR
responsePublished.Publish |> messageLoop (fun response -> printfn "Sent Response: %A" response)

Затем вы можете обновить ваш обработчик, чтобы вызвать события как требуется:

    let handler = Action<RequestMessage>(fun request ->        
        requestArrived.Trigger(request)
        let cabinetSubscribeId = sprintf "Project.%i" request.ProjectId
        let response = 
            match request.FrameType with 
            | FrameType.UNDEFINED -> 
                ResponseService.BusRequestFactory request data
            | _ -> 
                ResponseService.BusRequestFactory request data 
        bus.Publish<ResponseMessage>(response, cabinetSubscribeId)
        responsePublished.Trigger(response))
...