【发布时间】:2025-11-22 20:15:02
【问题描述】:
好的,这是一个非常简单和基本的问题。 如果我在 Windows 机器 A 上有一个应用程序想要写入 Windows 机器 B 上的队列,我是否需要在机器 A 上安装 MSMQ(即使那里没有队列)?我刚刚开始在我的应用程序中使用队列,并试图弄清楚一些基本原理。
谢谢
【问题讨论】:
好的,这是一个非常简单和基本的问题。 如果我在 Windows 机器 A 上有一个应用程序想要写入 Windows 机器 B 上的队列,我是否需要在机器 A 上安装 MSMQ(即使那里没有队列)?我刚刚开始在我的应用程序中使用队列,并试图弄清楚一些基本原理。
谢谢
【问题讨论】:
是的,您需要在本地安装 MSMQ 才能写入远程队列。如果您正在写入私有队列,请查看this page,其中包含有关如何格式化队列名称的有用信息。如果您正在写入远程事务队列,那么您需要确保正确指定(第 5 点)
这是文章正文:
1。使用远程队列时,
machinename\private$\queuename格式的队列名称不起作用。这导致一个 “无效的队列路径”错误。2。必须将队列名称称为
FormatName:Direct=OS:machinename\\private$\\queuename。这是必要的,因为队列访问是在内部使用格式完成的 仅限名称语法。另一个友好的表示被转换为 FormatName 然后使用。使用远程队列时,除非 有AD解析队列名称,友好名称不会 工作。详情请查看文档。
例如。
MessageQueue rmQ = new MessageQueue ("FormatName:Direct=OS:machinename\\private$\\queue"); rmQ.Send("sent to regular queue - Atul");3。更进一步,请注意 FormatName 区分大小写。如果您提到前面的字符串
FORMATNAME:Direct=OS:machinename\\private$\\queuename,不会的 工作。令人惊讶的是,在这种情况下没有抛出错误。 字符串的“FormatName”部分似乎是唯一区分大小写的 部分。其他的可以出现在不同的情况下。例如。你可以写 “直接的”。4。如果您想使用机器的 IP 地址,语法将是
FormatName:Direct=TCP:ipaddress\\private$\\queuename。例如。
MessageQueue rmQ = new MessageQueue ("FormatName:Direct=TCP:121.0.0.1\\private$\\queue"); rmQ.Send("sent to regular queue - Atul");5。您在代码中创建的队列实例的事务属性应与您尝试发送的队列的事务属性相匹配 消息给。所以在前面的例子中,我向一个 非事务队列。要发送到事务队列,代码 会是
MessageQueue rmTxnQ = new MessageQueue ("FormatName:Direct=OS:machinename\\private$\\queue"); rmTxnQ.Send("sent to Txn queue - Atul", MessageQueueTransactionType.Single);如果事务属性不匹配,则消息不会 发表。令人惊讶的部分是,我没有收到任何错误,并且 消息消失了
6。最后,当您向远程队列发送消息时,会在您自己的机器上创建一个临时的传出队列。这用于以防万一 远程队列不可用。如果你去电脑管理 控制台(compmgmt.msc),并展开服务和应用程序/ 消息队列/传出队列,您会看到这些队列。这 控制台右侧应显示包括状态在内的详细信息 (连接与否)和下一跳的 IP 地址。
【讨论】:
所有 MSMQ 通信都需要在每一端都有一个 MSMQ 队列管理器。 使用 MSMQ 的应用程序与为它们工作的本地队列管理器进行通信。 使用 MSMQ 的应用程序无法直接与任何本地或远程队列通信。
【讨论】:
另一个(而不是在运行客户端的本地计算机上安装 MSMQ)是实现 WCF 服务,该服务从 MSMQ 队列中获取消息。在这种情况下,您的远程客户端只需指定远程服务端点即可直接写入远程队列。您还必须注意远程队列的安全设置是否正确。
我认为这将是实现基于队列的通信的更好方式。这是一个简短的答案,但如果您有兴趣,我会很乐意扩展(我注意到您对另一个答案非常满意:)
【讨论】: