这是一个简单的问题,运行时不处理排队的消息。现在,当我将其作为Windows服务运行时,它不会处理私有队列中的消息(使用MSMQ)。MSMQ应用程序作为Windows服务
我试着以我的用户帐户和本地服务运行服务。在这两种情况下,队列中都充满了消息,其中没有一个正在处理。
请注意,Windows服务似乎运行正常:它是关联Wcf服务打开并收听。
只是为了确保它不是权限问题,我授予我可以想到的每个组/用户的完全访问权限。这是处理队列创建和主机初始化的代码。请注意,在这次尝试中,我将用户的本地化命名更改为他们的英文版本。另外请注意,我尝试在所有可能的帐户下安装该服务:我自己以管理员身份运行,LocalSystem,LocalService和NetworkService。
namespace MachineCommunication.ZeissCMMAdapter
{
partial class ZeissService : ServiceBase
{
public ZeissService()
{
InitializeComponent();
}
ServiceHost _host = null;
protected override void OnStart(string[] args)
{
Trace.WriteLine("Starting ZeissAdapter Service...");
string adapterQueueName = ConfigurationManager.AppSettings["adapterQueueName"];
// Create the transacted MSMQ queue if necessary.
MessageQueue adapterQueue;
if (!MessageQueue.Exists(adapterQueueName))
{
Trace.WriteLine("Creating Queue: " + adapterQueueName);
adapterQueue = MessageQueue.Create(adapterQueueName, true);
adapterQueue.SetPermissions(@"NT AUTHORITY\System", MessageQueueAccessRights.FullControl);
adapterQueue.SetPermissions(@"ANONYMOUS LOGON", MessageQueueAccessRights.FullControl);
adapterQueue.SetPermissions(@"Everyone", MessageQueueAccessRights.FullControl);
adapterQueue.SetPermissions(@"my_user", MessageQueueAccessRights.FullControl);
}
else
{
Trace.WriteLine("Queue already exists: " + adapterQueueName);
}
string machineQueueName = ConfigurationManager.AppSettings["machineQueueName"];
MessageQueue machineQueue;
// Create the transacted MSMQ queue if necessary.
if (!MessageQueue.Exists(machineQueueName))
{
Trace.WriteLine("Creating Queue: " + machineQueueName);
machineQueue = MessageQueue.Create(machineQueueName, true);
machineQueue.SetPermissions(@"NT AUTHORITY\System", MessageQueueAccessRights.FullControl);
machineQueue.SetPermissions(@"ANONYMOUS LOGON", MessageQueueAccessRights.FullControl);
machineQueue.SetPermissions(@"Everyone", MessageQueueAccessRights.FullControl);
machineQueue.SetPermissions(@"my_user", MessageQueueAccessRights.FullControl);
}
using (_host = new ServiceHost(typeof(ZeissAdapterService)))
{
_host.Open();
Console.WriteLine("The service is ready");
Console.WriteLine("Press <Enter> to stop the service.");
Console.ReadLine();
}
}
protected override void OnStop()
{
try
{
Trace.WriteLine("Shutting down Class-A E-mail Service...");
if (_host != null && _host.State == CommunicationState.Opened)
{
_host.Close();
_host = null;
}
}
catch (Exception ex)
{
Trace.WriteLine("Something went wrong closing the ServiceHost : " + ex.Message);
throw;
}
}
}
}
这里是我的服务全面的app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<!-- use appSetting to configure MSMQ queue name -->
<add key="adapterQueueName" value=".\private$\Zeiss/ZeissAdapterService"/>
<add key="machineQueueName" value=".\private$\Zeiss/ZeissMachineService"/>
</appSettings>
<system.serviceModel>
<services>
<service name="MachineCommunication.ZeissCMMAdapter.ZeissAdapterService" behaviorConfiguration="DefaultBehavior">
<!-- Define NetMsmqEndpoint -->
<host>
<baseAddresses>
<add baseAddress="http://localhost:12000/" />
</baseAddresses>
</host>
<endpoint address="net.msmq://localhost/private/Zeiss/ZeissAdapterService" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="MachineCommunication.Contracts.AdapterContracts.IAdapterService"/>
<endpoint address="net.msmq://localhost/private/Zeiss/ZeissMachineService" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="MachineCommunication.MachineTypeSpecificInfrastructure.ZeissInfrastructure.IZeissListener"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netMsmqBinding>
<binding name="TransactedBinding" deadLetterQueue="System" useActiveDirectory ="False" useMsmqTracing="True">
<security mode="None">
<message clientCredentialType="None"/>
<transport msmqAuthenticationMode="None" msmqProtectionLevel="None" />
</security>
</binding>
</netMsmqBinding>
</bindings>
</system.serviceModel>
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true">
<listeners>
<add name="sdt"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData= "SdrConfigExample.e2e" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
下面是重现该问题有点快捷方式:在分布式MSDN上的WCF代码样本,有两涉及客户端/服务器设置的MSMQ样例;我修改了这个示例,将服务器安装为Windows服务。如果运行服务器并启动客户端,则所有消息都应该停留在服务器的队列中,而不会进一步处理。这里是一个链接到该样本:
https://drive.google.com/file/d/0B5-APK5bfBpMUGU2cW5iaV9ybnM/edit?usp=sharing
对不起在上面的代码本地化用户/组。实际上,我确实给了“每个人”(Tout le monde),网络服务(SERVICERÉSEAU),本地服务等的完全访问权限。我还尝试以我自己的用户身份(以管理员权限)运行服务,作为本地服务,作为本地系统作为网络服务。队列总是保持不变(我删除了它,并且在每次尝试之前都为我所能想到的每个帐户分配了完整权限)。我将编辑我的文章,以包含更多可能对此问题负责的代码。感谢您的答复! – Strav 2014-08-30 02:13:39
如果以编程方式将绑定设置为MSMQ,该怎么办?我觉得它不是使用App.config通过MSMQ来收听,而是使用默认值来收听HTTP 我忘了确切的语法是什么,但它是这样的: _host.AddServiceEndpoint(typeof(MachineCommunication .MachineTypeSpecificInfrastructure.ZeissInfrastructure.IZeissListener) 新NetTcpBinding的(), “SomeName”); 而且在同一个MSMQ队列上也不可能有两个监听器。你们都应该为他们提供自己的队列。从配置中删除一个以进行测试。 – 2014-09-02 13:26:17