使用 MQManager.NET 浏览消息队列
改编一个停滞的开源项目以满足我的需求。
引言
Microsoft Message Queue (MSMQ) 技术是 Windows 开发人员常用的可靠消息传输协议。它之所以流行,主要原因在于它包含在所有版本的 Windows 操作系统中,并且一直受到 Microsoft 开发工具的良好支持。
我发现 Microsoft MSMQ 栈中一个不足之处是缺乏一个用于查看 MSMQ 中消息内容的良好工具。MSMQ MMC 管理单元适合管理系统上的队列,或者获取队列中的消息计数。然而,它不允许您检查消息内容。
市面上有一些高度成熟的商业工具试图填补这个空白。然而,我认为开源解决方案更适合我的需求。因此,我很快成为了一个名为 MQManager.NET 的被遗弃的开源项目的维护者。
我最初发现的 MQManager.NET
MQManager.NET 最初发布于 2005 年。此后一直停滞不前。它使用 Visual Studio .NET 2003 开发。它只能从消息队列反序列化 ActiveX 对象。这对我来说是个问题,因为我需要查看使用 BinaryMessageFormatter
序列化的消息。
此外,原始代码没有任何方法可以浏览给定主机上的消息队列。这很恼人,但短期内我可以接受。
开始的第一步
最初,我有三个顾虑。第一个是让这个软件适用于我的特定情况。我的第二个顾虑是联系项目的作者。我想尝试将我的改进纳入原始应用程序,以便当前用户能够受益。第三,我想利用该应用程序现有的任何社区。
让代码为我的特定情况工作足够简单。我允许使用 ActiveXMessageFormatter
、BinaryMessageFormatter
和 XmlMessageFormatter
,而不是假设消息体为 ActiveXMessageFormatter
。这使得代码达到了“足够好,可以完成当前任务”的程度。
在联系了原始开发人员之后,我被任命负责项目的未来。我获得了 SourceForge 项目的控制权,并被告知随心所欲,于是我便这么做了。
版本 0.2 和 0.3 - 我的第一个版本
此时我的主要关注点是为应用程序添加一些“润色”。我修复了窗体大小调整和其他一些小问题。我稍微清理了一下代码。我做了一些小而保守的更改,所以我敢于尽早频繁发布。
版本 0.4 和 0.4.1 - 引入主机队列浏览
是时候为应用程序添加新功能了。我需要应用程序能够浏览主机的消息队列,就像 MSMQ MMC 管理单元已经做的那样。
我想复制 MMC 的“主机 | 队列类型 | 队列”的树形层次结构。我想要比标准的 .NET TreeNode
控件更强大的东西。我恰好作为 SharpDevelop 的贡献者与 TreeViewAdv 一起工作过,并想找个机会写一个“从头开始”的实现。
实现 TreeViewAdv
我做的第一件事是实现了一个继承自 TreeNode
的新类。虽然目前不需要,但这在未来的开发中可能会派上用场。
using Aga.Controls.Tree;
using MQManager.SPI;
namespace MQManager.GUI.Forms
{
/// <summary>
/// A node for TreeViewAdv that handles
/// <see cref="IMessagingProvider"/>
/// </summary>
internal class MessagingProviderNode : Node
{
private IMessagingProvider _provider;
/// <summary>
/// The provider contained in this node.
/// </summary>
public IMessagingProvider Provider
{
get { return _provider; }
}
/// <summary>
/// Created a new <see cref="MessagingProviderNode"/>.
/// </summary>
/// <param name="messagingProvider">The instance
/// of <see cref="IMessagingProvider"/>.</param>
public MessagingProviderNode(IMessagingProvider messagingProvider) :
base(messagingProvider.Name)
{
_provider = messagingProvider;
}
}
}
TreeViewAdv 使用模型 - 视图 - 控制器 (MVC) 模式,因此对于熟悉大多数 .NET 控件的人来说,它不像它们那样直观。必须将模型与 TreeViewAdv 控件相关联,并且您可以通过这种方式添加节点。HostMSMQ 浏览器中的构造函数说明了这一点。
/// <summary>
/// Creates a HostMQMQ browser for the given host.
/// </summary>
/// <param name="hostName">The host to connect to. </param>
public HostMSMQBrowser(string hostName) : this()
{
_hostQueues = new MSMQHost(hostName);
_hostTreeModel = new TreeModel();
treeViewAdvHostQueues.Model = _hostTreeModel;
_privateQueues = new Node("Private Queues");
_publicQueues = new Node("Public Queues");
treeViewAdvHostQueues.BeginUpdate();
_hostTreeModel.Nodes.Add(_privateQueues);
_hostTreeModel.Nodes.Add(_publicQueues);
foreach (IMessagingProvider queueProvider in _hostQueues.PrivateQueues)
{
MessagingProviderNode node = new MessagingProviderNode(queueProvider);
_privateQueues.Nodes.Add(node);
}
foreach (IMessagingProvider queueProvider in _hostQueues.PublicQueues)
{
MessagingProviderNode node = new MessagingProviderNode(queueProvider);
_publicQueues.Nodes.Add(node);
}
treeViewAdvHostQueues.EndUpdate();
}
此时,您只能浏览本地计算机的 MSMQ,但只需进行微小的 UI 更改即可连接到您有足够权限访问的任何主机。这很快就会实现。
版本 0.5 - 更多功能
消息计数
我意识到 MSMQ MMC 中一个我错过的有用功能是消息计数列。我决定将其添加到我的主机队列视图中。这比预期的要困难。System.Messaging
命名空间中没有任何用于获取队列中消息计数的内容。快速搜索了一下 Google,找到了几种方法。它们是:
- 通过
System.Diagnostics
命名空间使用性能计数器。这需要额外的权限。 - 与 MSMQ COM 对象进行 COM 互操作。我从未走过这条路,但我愿意。
- C++ CLR 代码。我基本上讨厌 C++,而且这会导致我的应用程序在 Visual Studio Express 或 SharpDevelop 中无法编译。
- P/Invoke。这就是我选择的解决方案。虽然我必须启用不安全代码才能使其正常工作,但这是最优雅的,也是我最熟悉的方法。
添加 XmlVisualizer v2
下一个功能更像是“锦上添花”。但是,我认为它可能对某些人有用。我想要比纯文本框更复杂的邮件视图。至少,我希望能够在消息体被序列化为 XML 时对其进行语法高亮显示。
我当时知道一个理想的组件,它也在 CodeProject 上展示过,那就是 XML Visualizer v2。虽然它最初是作为 Visual Studio 的调试可视化工具开发的,但后来发布了一个不需要 Visual Studio 的独立版本。它能做我想要的一切,甚至更多。它由一位与我不同的人积极开发,我偶尔也会向他提供代码贡献,所以对我来说这是理想的选择。
未来方向
我已经概述了开发路线图并将其存储在项目的 subversion 存储库中。您可以随时从 此 URL 查看最新版本。我计划继续使用 TreeViewAdv 和 XMLVisualizer 等高级库添加功能。
我也想支持 ActiveMQ,然后研究 Mono 支持。但是,我也必须让所使用的库在 Mono 中正常工作。MSMQ 支持在 Mono 中将无法工作,但 ActiveMQ 可以。
关注点
一般来说,MSMQ 使用中一个有点烦人的地方是,您需要在机器上安装 MSMQ 支持,并且该机器上运行的消息服务应该能够连接到远程消息队列。这是因为 Microsoft Message Queuing 的设计。
更个人一点说,这是我做的第一个开源项目,我以如此大的程度重用了第三方组件。然而,尽管我依赖现有代码,但我所做的不仅仅是将积木连接在一起。我为 Lars 提供了许多关于 XmlVisualizer 的想法和补丁。此外,Lars 还很慷慨地将 XmlVisualizer 置于一个状态,让我无需修改即可重用 Visual Studio 项目之一。TreeViewAdv 是一个简单但强大的框架,我在其上构建了主机队列列表。此外,我还对原始 MQManager 代码本身进行了许多更改。最终,我可以自信地说,我通过“更聪明地工作而不是更辛苦地工作”,使 MQManager.NET 成为一个比我最初发现时更有用的软件。
特别感谢
- 感谢 Lars Hove Christiansen 编写 XML Visualizer v.2 并接受我的许多补丁和想法。
- 感谢 Andrey Gliznetsov 编写 TreeViewAdv 并应 David Srbecky 的要求授予我提交权限。
- 感谢 Gustavo Guerra 允许我使用 他的代码 通过 P/Invoke 获取队列的消息数。
另请参阅
SourceForge 项目 MQManager.NET。
历史
这是本文档的原始版本。