【问题标题】:MSMQ & WCF Messages not visible in private queueMSMQ 和 WCF 消息在专用队列中不可见
【发布时间】:2011-09-09 03:19:22
【问题描述】:

有几个类似的问题,我对MSMQ非常陌生。

我一直在尝试将 ServiceContract 和关联的 DataContract 链接到 MSMQ,并设置了端点,以便 DataContact 消息在 MSMQ 中结束。

我已验证 WCF 服务正确生成了消息,并且我还可以看到消息在我发送到的队列的日志中,但不在我期望它们的实际排队消息区域中.

我目前没有使用交易,并且我已将安全设置为无。我附上了相关代码,尽管我的感觉是由于对 MSMQ 的无知,我错过了一些基本的东西。任何指针将不胜感激。

服务和数据合同

[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);
}

WCF 主机的app.config

<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>
        <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="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange" />
                <host>
                    <baseAddresses>
                        <add baseAddress="http://localhost:8080/Registration/" />
                    </baseAddresses>
                </host>
            </service>
        </services>
    </system.serviceModel>
</configuration>

【问题讨论】:

    标签: wcf msmq


    【解决方案1】:

    我不知道 WCF,但我可以评论 MSMQ 方面。

    “我已验证该消息是 由 WCF 正确生成 服务,我也可以看到 消息在杂志上 我要发送到的队列,但不在队列中 我会在其中的实际排队消息区域 期待他们。”

    这意味着邮件已发送并已处理。
    与队列关联的日志消息仅在消息已被传递并被应用程序读取/接收时创建。
    如果一条消息刚刚传递但未读取/接收,则不会创建日志消息,原始消息将保留在目标队列中。
    如果消息已传递但随后被清除/删除,则不会创建日志消息,因为应用程序未成功读取/接收原始消息。

    干杯
    约翰·布雷克韦尔

    【讨论】:

    • 谢谢你。我确实怀疑这一点,但我仍然不确定为什么消息被消费/处理以及被什么处理!它可能与服务端点的配置方式有关,但我找不到任何关于发送(而不是处理)的信息,因为我想要一个单独的进程来处理消息。
    【解决方案2】:

    好吧,因为似乎没有人知道为什么要使用消息,所以我在使用本机 System.Messaging 类的服务实现中编写了一个解决方法。这是一种耻辱,因为根据文档,应该能够在没有代码的情况下将消息发送到队列(只要端点描述正确)。

    这是我使用的代码,适用于处于这种困境的任何人。

    在主机控制台项目中,我通过注释掉 net.msmq 并添加 wsHttpBinding 以使其成为常规 WCF 服务来修改 App.Config 端点。

            <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>
    

    在服务实现中,我添加了以下内容(保留原始 Console.WriteLine 语句用于测试目的:

        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);
        }
    

    这可以完美运行并按预期工作,从而为队列补水。现在我可以编写一个工作流基础服务来使用它。

    感谢 John 确认消息实际上已被消费。我会给你一票,但我的水平太低了:)

    【讨论】:

      猜你喜欢
      • 2017-06-29
      • 2012-12-24
      • 2015-06-21
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      • 2010-09-11
      相关资源
      最近更新 更多