Change to MSMQ URIs

Hope someone can help with this.  There appears to have been a change in the URIs required for MSMQ binding in the most recent WinFX release.  I used to use   "net.msmq://bleuchamp/batchjobconfirmation" in my app, but now this produces an exception

"The provided URI scheme 'net.msmq' is invalid; expected 'msmq.formatname'.
Parameter name: baseAddress

Anyone know what the correct new format is   This is a public queue, and it's being set programmatically - the queue name can be altered at runtime, so not possible via config file.  The exception is thrown by ServiceHost.Open(), the URI having previously been passed in as the 3rd parameter to

ServiceHost.AddServiceEndpoint(contract, binding, string)

Thanks

David



Answer this question

Change to MSMQ URIs

  • Teddy Chen

    Should also have included

    [Serializable]
    public struct JobConfirm
    {
       
    public bool success;
    }



  • abhishek.cbsa

    I'd greatly appreciate some comment on this.  To make it clearer, the code that fails looks like

    [ServiceContract]
    public interface IJobResponse
    {
       [OperationContract(IsOneWay = true, Action = "*")]
       [
    KnownType(typeof(JobConfirm))]
       void ProcessJobResponse(MsmqMessage<JobConfirm> msg);
    }


    [ServiceBehavior]
    public class JobResponseProcessor : IJobResponse
    {
       [OperationBehavior]
       void IJobResponse.ProcessJobResponse(MsmqMessage<JobConfirm> msg)
       {
       
    }
    }


    public static void InitMsgHandler()
    {
       JobResponseProcessor m_responseProcessor = 
                      new JobResponseProcessor();
       string sQueueName = "net.msmq://bleuchamp/batchjobconfirmation";

       ServiceHost m_queuedResponseProcessor = 
                      
    new ServiceHost(m_responseProcessor);

       MsmqIntegrationBinding binding = new MsmqIntegrationBinding();

       m_queuedResponseProcessor.AddServiceEndpoint(
             
    typeof(IJobResponse), binding, new Uri(sQueueName));

       m_queuedResponseProcessor.Open();
    }



  • Sushant Raut

    Ash,

    there appears to be another problem.  My client and server apps now work correctly - but only if the receiver is on the same machine as the queue!

    I'm running one XPPro SP2 and one server2003 SP1, both on a domain and with the same domain user account in use at both ends.  I've tried client and server apps on both machines and also moving the queue, but the result is always the same.  If the server is on the same machine as the queue, then everything works ok.  If the server and queue are on different machines, then the server receives and processes the first message and then doesn't receive any others.  Closing the ServiceHost and opening it again results in one additional message being received and processed.  The server app is not crashing and is not throwing any exceptions.  It just doesn't receive any more messages.

    This is all code which has been working for several months, so there's definitely something new introduced by Nov CTP compared to Beta1

    Any help appreciated.

    David


  • CharlesY

    Krish,

    the code in the example I posted above was

    MsmqIntegrationBinding binding = new MsmqIntegrationBinding();

       m_queuedResponseProcessor.AddServiceEndpoint(
             typeof(IJobResponse), binding, new Uri(sQueueName));


    So I think it's pretty clear I'm using MsmqIntegrationBinding.

    As noted above, the correct form of the URI is

    msmq.formatname:DIRECT=OS:hostname\queuename

    So far as I can establish, this format became traditional only in the last couple of months.  It certainly wasn't used with Beta 1, nor have I found any clear documentaion stating that this change had been made.  This is where the confusion arises.

    David



  • Kamyar Mohajerani

    Ash,

    thanks for the clarification.  Yes I know there was something wrong with the forums, I tried several times over a period of hours before I managed to post my findings.

    The change of the name format isn't a major issue - or it wouldn't be if someone warned you about it first, but the failure to throw an exception if the queue name is incorrect is much more serious.Appearing to work but then silently consuming all the available processor power it clearly not correct.  Hope this gets fixed.

    Now if only someone would tell me what happened to ServiceHost.Throttle and what I'm supposed to do instead, I'd be back to where I was two months or more ago.

    David


  • Anjan Das

    In the absence of any helpful suggestions - or any suggestions at all for that matter, a lot of experimentation produced an answer.

    The old URI

    net.msmq://bleuchamp/batchjobconfirmation

    is replaced with

    msmq.formatname:DIRECT=OS:bleuchamp\batchjobconfirmation

    note that the '/' characters in the original are now replaced with '\' and that the leading '//' has disappeared altogether.

    I'm sure we can all agree this is a great improvement and well worth any trouble it may have caused.

    It may also be helpful to know, that whilst beta 1 would throw an exception if the queuename was incorrect (queue didn't exist), the Nov CTP happily accepts whatever you give it and then sits and does nothing - except consume 100% of the available processor power.

     



  • hari.chinnan

    It gets worse!

    I gave up on ServiceHost and tried rewriting part of the app using the MessageQueue class directly, and it would appear the problem lies here.

    It looks like MessageQueue.Receive does not work correctly when directed at a remote (but on the same domain), public queue.  If the queue already contains a no. of messages, the first call to MessageQueue.Receive() works correctly, and returns the message.  A second call  appears simply to hang.

    Switching to MessageQueue.Receive(TimeSpan) does not help, because the timeout is not honoured, and the thread again just hangs on the second call to Receive.  If this is performed on a 2nd thread, then Thread.Abort() also doesn't work.  The thread's status changes to AbortRequested and stays there.  If this is all in an AppDomain, then AppDomain.Unload fails because it can't stop the thread!

    As previously noted, all of these functions work correctly exactly as expected if the receiver and the queue are on the same machine.

    David



  • Hans Groeneveld

    David,
    if I understand you correctly, your Indigo scenario tries to receive from the remote queue using MsmqIntegrationBinding with default settings.

    By default, since the ExactlyOnce knob is on, this will perform transactional read from the queue. For MSMQ 3 (WinXP/Win2k3) the remote transactional read doesn't work. This will be implemented only on Vista.

    You may try to turn the ExactlyOnce off and use nontransactional queue.

    leszek<g>

  • erSudev

    Hi David,

    I am glad you figured out the answer. Late last night I tried to post a response to your query but the kept getting an error from the forum. FWIW, here is what I had typed last night.

    Happy queueing,
    ash

    The way to address a queue when using Msmq Integration Binding has indeed changed.

    The error message you are getting is correct. You have to use msmq.formatname scheme to address queues when using the Msmq integration binding. E.g.

    string queue = msmq.formatname:<Formatname>;

    where <Formatname> - could be a DIRECT, PUBLIC or PRIVATE formatname.

    Since your scenario involves public queues you have the following options:

    1) Address the queue using a Direct format name. E.g. would be:
    msmq.formatname:DIRECT=OS:bleuchamp\batchjobconfirmation

    2) Address the queue using a Public format name. E.g. would be:
    msmq.formatname:Public=<queueGuid>

    note: you should be able to get the format name for case number 2 by using System messaging API.

    MessageQueue myQueue = new MessageQueue(@"bleuchamp\batchjobconfirmation");
    string integrationQueue = "msmq.formatname:" + myQueue.Formatname;


    All the best,
    ash



  • Emran Hussain

    Leszek,

    thanks for this.  Actually I spotted this fairly quickly after the URI format was sorted, so I now have

    MsmqIntegrationBinding binding = new MsmqIntegrationBinding();
    binding.Durable =
    false;
    binding.ExactlyOnce =
    false;

    These two boolean properties were a single property with an enumeration value in Beta1.  I'm not really sure why they changed it.

    If you read the new thread I started 'Is MSMQ broken '  you'll see the problem runs somewhat deeper than the WinFX classes and appears to stem from the MSMQ software itself.

    David



  • Molon Labe

    Hi David,
    Are you using the MsmqIntegrationBinding

    Let me explain. There are 2 queued bindings in Indigo -a NetMsmqBinding that is used when 2 WCF applications require queued communication using MSMQ and a MsmqIntegrationBinding that is used to by WCF applications to communicate with System.Messaging, or a COM+, or Win 32 MSMQ application using MSMQ.

    The NetMsmqBinding takes URI of the form net.msmq://, net.srmp:// and net.srmps//.

    The MsmqIntegrationBinding takes URI of the form msmq.formatname. The format name for your example public queue would be exactly the same way traditional MSMQ applications use format names. For information on use of format names refer to: http://msdn.microsoft.com/library/default.asp url=/library/en-us/msmq/msmq_about_queues_275f.asp

    Please let me know if this helps.

    Thanks
    krish


  • Change to MSMQ URIs