MSMQ 和WCF 消息在专用队列中不可见

发布于 2024-11-14 04:19:41 字数 2541 浏览 2 评论 0原文

有几个与此类似的问题,我对 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>

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

趁年轻赶紧闹 2024-11-21 04:19:41

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

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

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

干杯
约翰·布瑞克韦尔

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

内心荒芜 2024-11-21 04:19:41

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

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

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

        <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确认消息确实被消耗了,我会给你投票,但我的水平太低了:)

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文