selectively receiving

I have a scenario whereby I will have 200+ clients putting messages onto a service broker queue. This message will go through a pipes and filters based messaging system, and ultimately the message will pop out the other end.

Here's the question: what is a good way of making sure the same client gets the response to the message he received. Is there anyway I can selectively receive messages from a queue, i.e., pass a correlation id in with the message, and then filter messages based on that id.

Or if someone knows a better way to do it altogether i'd really appreciate it.

Many thanks,

Paul



Answer this question

selectively receiving

  • daph4ntom

    how are you sending back messages at the moment
  • Duncan Woods

    Yes i understand they each post to the same service which is you, but what are their service names How do you use bidirectional messaging with them , do you have a route configured for each client
  • Aneel

    Not as it stands currently, each client posts to the same service. I'm using the notion of a service here much like I would with say, a web service, just a single point of access many clients can communicate with.

    The message goes out into the clouds, then magically appears a few minutes later on another queue. I only want the client that sent it to know it exists.

    Cheers, Paul


  • Brad-RDA

    Sure you can do that with just one initiator service and one target service. The primitive of communication in Service Broker is a conversation (i.e. a persistent session over which you exchange messages). So your clients can certainly do a request response as follows:

    begin transaction;
    begin dialog @dh
    from service InitiatorService
    to service 'TargetService'
    on contract MyContract;
    send on conversation @dh message type MyRequest (N'<request/>');
    commit;
    begin transaction;
    waitfor (receive top(1) * from InitiatorQueue
    where conversation_handle=@dh), timeout @t;
    -- process the response
    commit;

    Hope that helps,

    Rushi


  • shiveta

    The conversation handles of the same conversation are different for different conversation endpoints. The conversation id is the same. The converation_id of a conversation uniquely identifies the conversation, where as the conversation_handle uniquely identifies the conversation endpoint. Since a dialog has two endpoints -- the initiator and target, each endpoint will have a different converation_handle.

    My example shows a standard pattern for doing request/response at the intiator side. If you have a different use case, please let me know exactly what you need so that I can suggest an alternative.

    Thanks,
    Rushi


  • IvanVC

    Hi Rushi,

    This is exactly the approach I'm looking for.  But when I  send a message, the value of @dh *isn't* the conversation_handle that is received on the otherside.  I changed your example to the following:

    declare @dh uniqueidentifier

    begin transaction;

    begin dialog @dh

    from service QuoteViewerOutTxSvc

    to service 'QuoteViewerOutRxSvc'

    on contract MsgContract;

    send on conversation @dh message type Msg (N'<request/>');

    commit;

    print @dh

    begin transaction;

    waitfor (receive top(1) * from QuoteViewerOutRxQueue

    where conversation_handle=@dh);

    -- process the response

    commit;

    This doesn't result in a message being received.  It simply sits there grinning at me.  Any clues

    Paul


  • goh6613

    How about if every client had its own queue. My message could have a Return Address, giving the name of that queue

    Would it be bad practice to open ~200+ queues (and the associated bits).

    I'm very new to Service Broker, it just seemed like a suitable replacement for MSMQ to handle queued messages. So far its doing great, just need to work out this last kink, then I'm home and dry!


  • Vassilux

    They all connect to the service called: CnmsInSvc. The clients just make an ado.net connection to the database, and execute:

    DECLARE @h uniqueidentifier
    BEGIN DIALOG CONVERSATION @h
    FROM SERVICE {0} TO SERVICE '{1}'
    ON CONTRACT {2};
    SEND ON CONVERSATION @h MESSAGE TYPE {3} (@MessageBody)
    END CONVERSATION @h WITH CLEANUP;

    I took this template code from this blog entry:

    http://blogs.msdn.com/ericnel/archive/2005/03/15/395793.aspx

    I run a .NET format over this string to give it the right details.

    I'm literally just using service broker as a one-way channel so that messages can jump from one process / server to another. And it's worked perfectly for this so far, just this last kink.

    Please excuse my ignorance if I'm abusing service broker!

    Many thanks,

    Paul


  • tovarish

    Hi There

    Does each client have a different initiator service name


  • selectively receiving