none
Push mechanism for Topic Subscription

    Question

  • Hello,

    I want to implement a Push concept for the Topic subscription...Whenever a message arrives to a subscription i want to notify a client running in my local domain...How to implement this scenario?...


    A.Navarajan

    Tuesday, March 20, 2012 7:33 AM

Answers

  • Yes, that call is, but the recommended API is asynchronous and as such you do

    'subscriptionClient.BeginReceive(TimeSpan.FromMilliseconds(200), (s, args) => { if (args.Message != null) router.Consume(args.Message); }) where router could be: 'class Router { public void Consume(BrokeredMessage m) { _routeTable[m.Headers["MessageType"]].Enumerate(m).ForEach(consumer => consumer.Consume(m)) }'

    That way you'll get callbacks on the thread-pool in a push-fashion. The problem with the above "pusher" is that latency probably will kill its aim; of bringing down the time taken from a queue receiving a message, to a consumer getting it; because it has all kinds of overheads and extra couplings.

    The above is what my project MassTransit Transport does (albeit a bit more elaborate, with transient fault handling etc...) - so why don't you try it out?

    Thursday, March 22, 2012 9:17 AM

All replies

  • Have you looked at SignalR?
    Tuesday, March 20, 2012 7:38 AM
  • Hi,

    What technology are you using to implement the client?

    You could use the traditional technique for receiving messages:

    http://www.cloudcasts.net/devguide/Default.aspx?id=12042

    As the clients use "sticky polling" you will get low latency.

    http://www.cloudcasts.net/devguide/Default.aspx?id=12043

    You will have to work out the connection charges for using the service bus, it may get expensive with a lot of clients...

    Regards,

    Alan


    http://www.CloudCasts.net - Community Webcasts Powered by Azure

    Tuesday, March 20, 2012 7:47 AM
  • Hello Lucifure,

    I have heard about that...But i want to implement my scenario using Topic&Subscription model only...Is it possible?


    A.Navarajan

    Tuesday, March 20, 2012 7:48 AM
  • Hi Alan,

    I am implementing the client using WCF... I want to get the notification from the worker role to the app running on my local domain...i have decided to use the Topic-subscription model to publish the messages...now the client has to get the notification when messages available in the subscription by Push... 

           If you have any idea to implement the "server push to client" scenario then suggest me... 


    A.Navarajan



    Tuesday, March 20, 2012 8:14 AM
  • You can have a look at https://github.com/MassTransit/MassTransit-AzureServiceBus

    Create a message assembly, with your message as an interface.

    From your worker application you do:

    bus.Publish<MyInterface>(new Impl{ Date = "Hello World })

    From your local application you do configure a subscriber:

    var bus = ServiceBusFactory.New(sbc=> {
      sbc.Subscribe(s => s.Consumer<MyConsumer>())
      sbc.ReceiveFromComponents("owner", "bjOAWQJalkmd9LKas0lsdklkdw4mAHwKZUJ1jKwTLdc=", 
                                  "myNamespace", "my-application");
      sbc.UseAzureServiceBusRouting();
    })
    Here's the consumer:
    class MyConsumer : Consumes<MyInterface>.All { 
      public void Consume(MyInterface message) {
      }
    }
    Now you have pub-sub with push set up and MassTransit will handle the boring details for you.
    Tuesday, March 20, 2012 9:04 AM
  • I believe there is not default support on the service bus for push operations. You will have to use a form of pulling to get messages of the subscription. Besides, using a push-model will force you to open inbound connections on your machine instead of just the outbound connections, which could expose a security risk.

    Be nice to nerds ... Chances are you'll end up working for one!

    Tuesday, March 20, 2012 11:29 AM
  • It's not true that having push forces you to open an inbound connection. If you have a TCP socket open, that socket is bi-directional.
    Tuesday, March 20, 2012 12:04 PM
  • A.Navarajan,

    Definitely possible to use topic and subscription to accomplish this, but as the other responders have indicated, first this is not really a push and secondly it can get expensive.

    Really the solution depends on your performance and scalability needs.
    Will you have multiple clients?
    Do all clients receive all messages? (Need to use topic/subscription or just queues).
    How soon do the clients need to receive the message? (Infrequent polling is cheaper).


    I suspect a better understanding of your requirements is needed to arrive at an optimal answer.

    Tuesday, March 20, 2012 3:58 PM
  • Hi A.Navarajan,

    My upcoming (end of this month) article Azure Service Bus Pusher on the codeproject can help you for this solution. The Azure Service Bus Pusher concept is based on the pulling a brokered message by WCF Subscriber and forwarding (pushing) this message to the target endpoint.

    The following screen snippet shows this scenario:

     

    Features

    • Pub/Sub-Push Model (PushAndPush model)
    • Virtual Hosting for Subscribers and Receivers in the WorkerRole
    • Table Storage for runtime and configuration Repository
    • Pub/Sub Controller for managing WorkerRole
    • No external endpoints
    • Target endpoint for Brokered Message
    • Target endpoint for BasicHttpBinding
    • Pushing messages across the namespaces, topics, etc.
    • Option to send a BrokeredMessageProperty Header
    • Option for Message Version (default is Soap12)
    • Direct or Indirect Push addressing
    • Windows Azure Service Bus Messaging (November 2011)
    • WCF Technology

    This article will describe a Push Service for Service Bus Components. The Pusher enables to use a Push Model for delivery an event interest from the Service Bus Components such as Queue and Topic. The Table Storage (Repository) allows you to create a runtime mapping of the Subscribers or Receivers to the Target endpoints in the Push model driven architecture.

    Thanks

    Roman


    Roman Kiss, MVP Connected System Developer





    • Edited by Roman Kiss Tuesday, April 03, 2012 8:58 PM
    Tuesday, March 20, 2012 4:27 PM
  • Hi Lucifure,

         Yes I have multiple clients...and a message sent to only one client based on rules in subscription...The client need that message instantly...

        Can i get your Live ID? (navarajan.a@live.com)


    A.Navarajan

    Tuesday, March 20, 2012 5:01 PM
  • Hi Roman,

           Great to see your scenario... I wonder how you are pushing the messages to the service running in our local domain...I am eagerly waiting for your article... can i get your live id? mine is navarajan.a@live.com


    A.Navarajan

    Tuesday, March 20, 2012 5:07 PM
  • A.Navarajan,

    As you can see, the Pusher is assigned to the Queue and/or to the specific Rule of the Subscription. Basically, the Pusher can push the message to the Queue/Topic across the namespace or to the BasicHttpBinding endpoint with an option for injecting a BrokeredMessageProperty header.

    In other cases (such as special endpoint, adapter, etc.), the brokered message can be pushed to the bridge (EAI&EDI) for its mediation (VETER pattern)

    Thanks
    Roman


    Roman Kiss, MVP Connected System Developer


    • Edited by Roman Kiss Tuesday, March 20, 2012 6:40 PM
    Tuesday, March 20, 2012 6:23 PM
  • Hi Roman,

            I cant guess the internal logic for your scenario...Once you have published your article then please share the link here...


    A.Navarajan

    Wednesday, March 21, 2012 6:30 AM
  • Why can it get expensive to a use a polling consumer?

    Let's a simple calculation. ASB is billed by the # messages and by the outbound transfers in $.12/GB, right?

    Now, with no messages, you only have the overhead of the polling; with messages you have the overhead of the polling + the cost of transferring the actual message data. No matter how you twist and turn, you will always pay for outbound transfers. That leaves the polling cost. Let's assume that you don't need to poll every instant (i.e. you don't need outstanding asynchronous request at every point in the timeline) - you would have a latency of about 200 ms anyway - so we say - let's poll every 1 second. Let's also assume a quite large overhead per polled message (SOAP envelope + IEnumerable<BrokeredMessage> that is empty) of 5 KiB.

    That's 3600 polls per hour = $0.0 in message transfers + $.12 * (1024 * 5 * 3600) / 1024^3 = $.0021 per hour. That's $1.48 per month per consumer.

    Hardly expensive. Now, let's look at how "Push" Romans' suggestion is.

    Wednesday, March 21, 2012 7:20 PM
  • Since I don't know how you store data or how you poll the table storage that doesn't go into the cost. Let's just take the computer; $0.12/h = $86 month.

    From the above calculation you'll need at least 58 polling consumers that poll every second to reach that cost.

    But that's not all; you'll also get different consistency semantics - because you're essentially lifting out messages into memory; but then you need to re-implement the ACK-protocol that BrokeredMessage.Complete() implements, but in your 'pusher' as well.

    This thread reminds me of why I don't like forums very much...

    Wednesday, March 21, 2012 7:26 PM
  • Hi Henrik,

    Consider i am using Topic-Subscriber for publishing and subscribing the message...

            In the Subscriber side i am using  subscriptionClient.Receive(TimeSpan.MaxValue) to fetch the value...so it is not polling right? It is a kind of blocking call right...It will block untill the message is available in the subscription end...


    Navarajan

    Thursday, March 22, 2012 7:11 AM
  • Yes, that call is, but the recommended API is asynchronous and as such you do

    'subscriptionClient.BeginReceive(TimeSpan.FromMilliseconds(200), (s, args) => { if (args.Message != null) router.Consume(args.Message); }) where router could be: 'class Router { public void Consume(BrokeredMessage m) { _routeTable[m.Headers["MessageType"]].Enumerate(m).ForEach(consumer => consumer.Consume(m)) }'

    That way you'll get callbacks on the thread-pool in a push-fashion. The problem with the above "pusher" is that latency probably will kill its aim; of bringing down the time taken from a queue receiving a message, to a consumer getting it; because it has all kinds of overheads and extra couplings.

    The above is what my project MassTransit Transport does (albeit a bit more elaborate, with transient fault handling etc...) - so why don't you try it out?

    Thursday, March 22, 2012 9:17 AM
  • Hi Hendrik,

    Ok if i implement Async Receive method then no blocking is required and we will get event notification when message will be available and we can retrieve the message using endReceive right... so it will reduce the cost because no need to polling...

    I cant understand what are you doing in Router Class...It will be nice and useful if you write a article about how your MassTransist Transport works. 


    Navarajan

    Thursday, March 22, 2012 10:02 AM
  • Well, it's still polling in a sense, because the whole service bus (client API and endpoint facade) is built on WCF and WCF is RPC in its core; so in order to get a response you need a request.

    If you truly require push then you might want to wait until this is available (FF to minute 14). But my gut feeling is that you don't need that necessarily, but what you need is asynchronous, non-blocking receiving where the framework calls your consumers rather than your consumers doing the polling; this is what the transport gives you.

    If I were to write an article; what points would you consider important to discuss in that article? What are you major thoughts and quandaries that you'd like to have answered by such an article?

    Thursday, March 22, 2012 10:44 AM
  • Hi Henrik,

    whether the async method will be cost effective than the sync one?

            Yes, you can describe the need of MassTransist ,how it works? and how we can use it in our projects?...so we can understand it at depth...


    Navarajan

    Thursday, March 22, 2012 11:32 AM
  • Yes it will, given certain conditions; because some features such as batching of messages are unavailable in the synchronous version.

    I'll post if I write something up.

    Thursday, March 22, 2012 11:58 AM
  • Thank you Henrik... You should write one, Then only beginners like me can use it well... I am looking forward to read your article...

    Navarajan

    Thursday, March 22, 2012 12:07 PM
  • Navarajan,

    - The link to my article is Azure Service Bus Pusher.

    Thanks

    Roman


    Roman Kiss, MVP Connected System Developer

    Sunday, April 01, 2012 7:41 AM