问题
I have a local private queue. I also have a WCF-service inside an MVC-application that listens to the queue using msmqIntegrationBinding. The problem is that the service contract is never invoked when a message is queued but the message disapears the moment after. The message is not in the poison queue. Here is the config-part where i declare the binding to the queue:
<services>
<service name="SkruvInfo.Web.Service.QueueMessageReceiver">
<endpoint address="msmq.formatname:DIRECT=OS:LEIA\private$\screwinfo_autotests_messagequeue"
binding="msmqIntegrationBinding"
bindingConfiguration="MsmqBinding"
contract="SkruvInfo.Web.Service.IQueueMessageReceiver" />
</service>
</services>
And here is the contract:
[ServiceContract(Namespace = "http://localhost/SkruvWeb/Service")]
public interface IQueueMessageReceiver
{
[OperationContract(IsOneWay = true, Action = "*")]
void PutScrewInfoMessage(MsmqMessage<string> msg);
}
And here is the method in the service:
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void PutScrewInfoMessage(System.ServiceModel.MsmqIntegration.MsmqMessage<string> msg)
{
log4net.Config.XmlConfigurator.Configure();
var log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
try
{
log.Debug("Message from queue: " + msg.Body.ToString(CultureInfo.InvariantCulture));
var xDoc = new XmlDocument();
xDoc.LoadXml(msg.Body);
CacheScrewInfoModelFromScrewInfoXmlDoc(xDoc);
}
catch (Exception e)
{
log.Error("Error parsing message from queue",e);
EventLog.WriteEntry("Application","Message error for screws");
}
}
Any suggestions to why the message disapears but does not invoke the service?
回答1:
Try to modify your service contract with ServiceKnownType attribute:
[ServiceContract(Namespace = "http://localhost/SkruvWeb/Service")]
[ServiceKnownType(typeof(String))]
public interface IQueueMessageReceiver
{
[OperationContract(IsOneWay = true, Action = "*")]
void PutScrewInfoMessage(MsmqMessage<string> msg);
}
UPDATE
If you are using MsmqIntegrationBinding I am assuming your queue client is a legacy application like a VB6 client? If so you will need to specify the serialization format in your service binding configuration. For example:
<msmqIntegrationBinding>
<binding name="MsmqBinding" serializationFormat="ActiveX">
<security mode="None" />
</binding>
</msmqIntegrationBinding>
Permissable values are documented here.
回答2:
In my my experience this behaviour is caused by either a serialization failure or a message that is to large (64KB is the default max messages size). This causes WCF to crash silently (yes, I don't understand that design choice either), but still remove the message from the queue.
Just enable Tracing and you'll quickly see the exception in WCF that causes this.
Add this to your web.config (I have it just below </system.webServer>) for a crude trace setup. Make sure the AppPool user has write access to the logging folder.
<system.diagnostics>
<trace autoflush="true" indentsize="4" />
<sources>
<source name="System.ServiceModel" switchValue="Warning">
<listeners>
<add name="textLogger" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="textLogger"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\logs\webbackend_wcf_log.txt" />
</system.diagnostics>
来源:https://stackoverflow.com/questions/11645131/msmq-message-is-put-on-queue-and-disapears-but-is-never-picked-up-by-service-co