Peter Wone
Peter Wone

Reputation: 18805

WCF MSMQ fires only once

I'e written a C# WCF service that's supposed to handle incoming messages, parse the XML they contain and transcribe the data to a database table.

When I start the Windows Service that hosts my WCF MSMQ service implementation, it processes one message successfully and then stops.

This used to process all messages in the queue until I started renaming things. I'm at a bit of a loss, because it does get invoked - but only once. No errors are logged in the event log. The Window Service host continues to run, and responds promptly to a service stop instruction from the SCM.

  <netMsmqBinding>
    <binding name="Binding.MSMQ.TransportSecurity" maxReceivedMessageSize="32767">
      <readerQuotas maxBytesPerRead="32767" maxStringContentLength="32767" maxArrayLength="32767"/>
      <security mode="Transport">
        <transport msmqAuthenticationMode="None" msmqEncryptionAlgorithm="RC4Stream"
            msmqProtectionLevel="None" msmqSecureHashAlgorithm="Sha1" />
        <message clientCredentialType="Windows" />
      </security>
    </binding>
  </netMsmqBinding>

...

<services>
  <service behaviorConfiguration="Behavior.CommonSense.ChapterWriter"
    name="CommonSense.ChapterWriter">
    <endpoint address="net.msmq://localhost/private/bob.logwriter"
      binding="netMsmqBinding" bindingConfiguration="Binding.MSMQ.TransportSecurity"
      name="Endpoint.CommonSense.ChapterWriter.msmq" contract="CommonSense.IChapterWriter">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost/CommonSense/ChapterWriter/" />
      </baseAddresses>
    </host>
  </service>
</services>

...

using System.ServiceModel;

namespace CommonSense
{
  [ServiceContract]
  public interface IChapterWriter
  {
    [OperationContract(IsOneWay = true)]
    void Write(string xml);
  }
}

Upvotes: 0

Views: 554

Answers (1)

Peter Wone
Peter Wone

Reputation: 18805

The problem was buffer size

It wasn't running the first time, it was running once.

The message generator used in my test case happens to be configured such that it produces two large messages and a small one (16K). The small one was processing normally and as soon as a large one was encountered a fatal exception would derail the WCF service without stopping the wait thread of the Windows Service host process.

Increasing various buffer sizes resolved the problem completely. If you see similar behaviour, visit the ReaderQuotas settings and the binding maxReceivedMessageSize. WCF Config Editor makes this easy.

<netMsmqBinding> 
  <binding name="Binding.MSMQ.TransportSecurity" maxReceivedMessageSize="65535"> 
    <readerQuotas 
      maxBytesPerRead="65535" 
      maxStringContentLength="65535" 
      maxArrayLength="65535"/> 
    <security mode="Transport"> 
      <transport msmqAuthenticationMode="None" msmqEncryptionAlgorithm="RC4Stream" 
          msmqProtectionLevel="None" msmqSecureHashAlgorithm="Sha1" /> 
      <message clientCredentialType="Windows" /> 
    </security> 
  </binding> 
</netMsmqBinding> 

WCF Configuration Editor

I cannot recommend this tool highly enough. While I already have a pretty good idea of how to configure WCF, boilerplating without accidental omissions is valuable, as is the impossibility of mistyping a name when referring to it.

This tool was was present in the Tools menu of Visual Studio, but the path to the exe is in the Windows SDK so I'm not sure how it got onto my system, but I am sure google or Bing can help you if you don't already have it.

Upvotes: 2

Related Questions