There have been a few questions similar to this, and I am VERY new to MSMQ.
I have been trying to link a ServiceContract and associated DataContract to MSMQ and have set up endpoints so that the DataContact message ends up in MSMQ.
I have verified that the message is being correctly generated by the WCF service and I can also see that messages are in the Journal of the queue I am sending to, but not in the actual Queued Message area where I'd expect them.
I am not using transactions at the moment, and I have set security to none. I attach the relevant code, though my feeling is that I am missing something fundamental through ignorance of MSMQ. Any pointers would be appreciated.
Service & Data Contracts
[DataContract]
public class RegistrationMessage : IRegistrationMessage
{
[DataMember]
public string EMailAddress { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
}
[ServiceContract]
public interface IRegistration
{
[OperationContract(IsOneWay = true)]
void Register(RegistrationMessage message);
}
app.config of the WCF host
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MetaDataBehaviour">
<serviceMetadata httpGetEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netMsmqBinding>
<binding name="msmq"
deadLetterQueue="System" durable="true"
exactlyOnce="false"
receiveContextEnabled="false"
useMsmqTracing="true">
<security mode="None" />
</binding>
</netMsmqBinding>
</bindings>
<s开发者_开发技巧ervices>
<service behaviorConfiguration="MetaDataBehaviour" name="Client.AuthenticationService.RegistrationService">
<endpoint address="net.msmq://localhost/private/AuthenticationQueue"
binding="netMsmqBinding"
bindingConfiguration="msmq" name="msmq"
contract="Global.DomainModel.IRegistration" />
<endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/Registration/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
I don't know WCF but I can comment on the MSMQ side.
"I have verified that the message is being correctly generated by the WCF service and I can also see that messages are in the Journal of the queue I am sending to, but not in the actual Queued Message area where I'd expect them."
This means that the message was delivered AND processed.
Journal messages associated with a queue are only created when the message has been delivered AND then read/received by an application.
If a message was just delivered and not read/received then there would not be a journal message created yet and the original would remain in the destination queue.
If a message was delivered but then purged/deleted, there would not be a journal message created as the original message was not read/received successfully by an application.
Cheers
John Breakwell
Well, since no-one seems to have an answer to why the messages are being consumed, I have written a workaround in the service implementation which uses the native System.Messaging classes. This is a shame because according to the documentation, one should be able to send a message to a queue without code (as long as the endpoints are described correctly).
Here is the code I have used, for anyone in this predicament.
In the host console project, I modified the App.Config endpoint by commenting out the net.msmq and adding a wsHttpBinding to make it a regular WCF service.
<services>
<service behaviorConfiguration="MetaDataBehaviour" name="Client.AuthenticationService.RegistrationService">
<!-- <endpoint address="net.msmq://localhost/private/authenticationqueue"
binding="netMsmqBinding"
bindingConfiguration="msmq"
name="msmq"
contract="Global.DomainModel.IRegistration" /> -->
<endpoint address="http://localhost:8080/Registration"
binding="wsHttpBinding"
bindingConfiguration=""
contract="Global.DomainModel.IRegistration" />
<endpoint address="mex"
binding="mexHttpBinding"
name="mex"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/Registration/" />
</baseAddresses>
</host>
</service>
In the service implementation, I added the following (leaving the original Console.WriteLine statements in for testing purposes:
public void Register(RegistrationMessage message)
{
MessageQueue queue = new MessageQueue(@".\private$\authenticationqueue");
Message msg = new Message();
msg.ResponseQueue = queue;
msg.Label = "AuthenticationMessage";
msg.Body = message;
queue.Send(msg);
Console.WriteLine("e-mail: " + message.EMailAddress);
Console.WriteLine("First Name: " + message.FirstName);
Console.WriteLine("Last Name: " + message.LastName);
}
This works perfectly and works as expected, hydrating the queue. Now I can write a workflow foundation service to consume it.
Thanks to John for confirming the fact that messages were, in fact, being consumed. I would give you a vote but my level is too low :)
精彩评论