65.9K
CodeProject 正在变化。 阅读更多。
Home

在 C# 应用程序中使用 JMS 消息传递

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (6投票s)

2006年2月2日

8分钟阅读

viewsIcon

173804

downloadIcon

1755

Java 消息系统 (JMS) API 定义了一种强大的消息队列技术。在此了解如何从 C# 应用程序访问它。

 

使用 Visual MainWin for J2EE 和 OpenJMS  轻松实现消息传递

Java™ 应用程序中使用的一个常见 API 是 JMS API,它允许您实现托管消息和消息队列。当使用 Mainsoft 的 Visual MainWin for J2EE(又名 Grasshopper)时,您可以从 JAR 文件或 EJB 中消耗和使用 Java 资源。在本文中,您将学习如何在 Grasshopper 应用程序中使用 C# 或 VB.NET 直接与此 API 的 OpenJMS 实现的 Java 代码进行交互。然后,您可以使用它在 Visual Studio .NET® 开发环境中使用此来编写和调试 JMS 应用程序。

 

概述

Grasshopper 是 Mainsoft 提供的免费 Visual Studio .NET IDE 插件,它允许您使用 .NET 语言编写应用程序,然后通过将 MSIL 代码转换为 Java 字节码来在 J2EE 上重新编译和重新托管它们。此外,它还有一个强大的方面,那就是您可以在同一个应用程序中混合使用 Java 和 .NET 代码,并且仍然可以从 Visual Studio .NET IDE 中编写、调试和部署。  这其中许多出色的方面之一是,您可以像编写原生 Java 一样消耗您的 Java 资产。  结果是一个统一的运行时堆栈,其中.NET/J2EE在字节码级别实现了互操作性。   

一个典型的场景是应用程序具有 ASP.NET 前端和一个 Java 后端。为了与 Java 后端接口,您可以使用昂贵的桥接或其他互操作性解决方案。但如果高性能是要求,Web 服务和桥接可能不可行。

消息传递的开放标准 JMS API 是一个很好的例子,说明如何使用 Grasshopper 混合 Java 和 .NET 代码。JMS 是一个开放标准,因此有许多供应商竞相提供其实现和配件(如管理平台)。这为您提供了极大的选择空间,并帮助您找到价格合适的供应商。但除非您使用某种形式的消息桥接来增加复杂性和成本,否则它对 .NET 是封闭的。

在本文中,您将逐步了解如何通过直接访问源头——即消耗 OpenJMS JAR 文件——轻松地使用免费 OpenJMS 消息服务器进行 JMS 消息传递。

入门。

要开始,您需要 Grasshopper 1.7,可以从 http://dev.mainsoft.com/ 下载。您还需要 Tomcat 5.5,它将作为 Grasshopper 安装的一部分为您安装。  如果您想使用 IBM WebSphere®、BEA WebLogic® 或 JBoss®,您也可以这样做,但您需要 Visual MainWin® for J2EE™ 的企业版,可以从同一个地方下载。

最后,您需要一个消息服务器,我推荐的并且在本文中使用的服务器是 OpenJMS 服务器,它是 Tomcat 的标准消息队列 MOM(面向消息的中间件)。您可以从 http://openjms.sourceforge.net/ 下载

安装 OpenJMS 非常简单。只需下载二进制文件,然后将其解压缩到您的硬盘驱动器。然后,将环境变量 OPENJMS_HOME 设置为您解压缩它们的位置。在本例中,我将它们放在目录 C:\jms\openjms-0.7.7-alpha-3 中,因此将系统环境变量设置为此值。在 Windows 中执行此操作,右键单击桌面上的“我的电脑”,然后选择“属性”。

然后,在“高级”选项卡(图 1)中选择“环境变量”。

图 1. 环境变量设置。

 对话框将显示用户变量和系统变量(图 2)。

图 2. 环境变量对话框

 在系统变量区域,单击“新建”,然后输入变量名和值,如图 3 所示。请注意,变量值在您的系统上可能不同。您应将其设置为解压缩 openjms 的目录名称。

图 3. 设置环境变量。

 如果您系统中没有 JRE 或 JDK,您应该下载并安装一个,并确保您的 JAVA_HOME 系统变量已设置为其安装目录。对于标准 JRE 安装,默认值是 C:\Program Files\Java\jre1.5.0_06。

设置好所有这些后,从 DOS 命令,切换到您安装 OpenJMS 目录下的“bin”目录,然后发出“openjms run”命令。您应该会看到类似图 4 中的输出。

图 4. 在命令控制台中运行 OpenJMS。

构建消息命名空间。

下一步是构建消息命名空间。这将包含您将用于包装底层 JMS API 的类,以便在您的应用程序中轻松使用它们。从 Visual Studio.NET,执行“文件”->“新建”->“项目”请求,然后从“Visual MainWin C# for J2EE Projects”文件夹中选择“类库”。(参见图 5)。

图 5. 创建新的 System.Messaging 命名空间。

这将创建一个新的类库,其中包含一个名为“Class1.cs”的类。删除此库中的所有代码,并替换为本文下载中的 System.Messaging 代码。

接下来,您需要添加对 OpenJMS JAR 文件的引用。您可以通过右键单击“解决方案资源管理器”中的“引用”节点并选择“添加 Java 引用”来完成此操作。这将打开一个通用对话框。使用它来浏览 OpenJMS 安装目录下的“lib”目录。例如,如果您将 OpenJMS 文件解压缩到 C:\jms 目录,则浏览到 C:\jms\openjms-0.7.7-alpha-3\lib。

选择这些 JAR 添加引用——导入可能需要几分钟才能完成

  • commons-codec-1.3.jar
  • commons-logging-1.0.4.jar
  • concurrent-1.3.4.jar
  • jms-1.1.jar
  • jndi-1.2.1.jar
  • openjms-0.7.7-alpha-1.jar
  • openjms-common-0.7.7-alpha-1.jar
  • openjms-net-0.7.7-alpha-1.jar
  • spice-jndikit-1.1.jar

您现在应该能够编译您的类库。如果您遇到任何编译错误,请检查您是否正确导入了上面提到的所有 JAR 文件。如果不行,此库的完整 Visual Studio 解决方案可在下载文件中找到。

构建消息发送器

接下来,您将构建一个简单的控制台应用程序,该应用程序将消息发送到消息队列。由于您上面构建的类库,这变得非常简单。

要开始,请在 Visual Studio.NET 中选择“文件”->“新建”->“项目”。从“Visual MainWin C# for J2EE”文件夹中选择“控制台应用程序”,并将其命名为“Message Sender”。

创建解决方案后,添加一个 JAR 引用到 System.Messaging.jar——您之前构建的类库。除非您已将其部署到其他地方,否则您会在其项目文件夹中找到它。

然后,添加与创建库时相同的 JAR Java 引用。

在 Class1.cs 的顶部,添加以下“using”指令

using System;
using System.Messaging;
using javax.naming;
using javax.jms;

最后,在 Main 方法中,您将添加实现消息队列的代码。您将从设置消息传递环境的代码开始,通过设置其 Context 对象的属性来实现

static void Main(string[] args)
{
  java.util.Hashtable properties = new java.util.Hashtable(); 
  properties.put(Context__Finals.PROVIDER_URL, "tcp://:3035"); 
  properties.put(Context__Finals.INITIAL_CONTEXT_FACTORY, 
                 "org.exolab.jms.jndi.InitialContextFactory"); 
  properties.put(Context__Finals.SECURITY_PRINCIPAL, "admin"); 
  properties.put(Context__Finals.SECURITY_CREDENTIALS, "openjms");

要了解更多关于这些属性及其作用的信息,请查阅 OpenJMS 文档。

在您的 Main 方法的其余部分,您将发送 10 条带有当前时间的消息到消息队列。在监听器未激活的情况下运行它是安全的。OpenJMS 将为您处理队列,直到您准备好取出它们。

string queueServer = "localhost"; 
  string queueName = "queue1"; 

  int N = 10; 
  if (args != null && args.Length > 0) 
  { 
    N = Convert.ToInt32(args[0]); 
  } 

  for (int i = 0; i < N; i++) 
  { 
    System.Messaging.Message theMessage = new System.Messaging.Message(); 
    theMessage.Body = "test value " + i 
                   + " " + System.DateTime.Now.ToShortTimeString(); 
    MessageQueue mq = new MessageQueue("FormatName:DIRECT=OS:" + 
                         queueServer + "\\" + queueName); 
    mq.Send(theMessage); 
    Console.WriteLine("Sent Message: {0}", theMessage.Body); 
  } 
  Console.ReadLine();
  java.lang.System.exit(0);
}

运行此应用程序将发送在参数中指定的数量的消息到队列,如果未指定参数,则会发送 10 条消息,如图 6 所示。此应用程序的核心在于 for 循环。它只需设置一个 System.Messaging.Message 对象(在您之前创建的类库中找到),并将其正文初始化为字符串“test value”以及当前日期和时间。然后,它实例化一个 messagequeue 对象,并将其设置为本地服务器和名为 queue1 的队列,queue1 是 OpenJMS 中预定义的队列。然后,调用此队列上的 send 方法,并将消息作为参数传递。非常简单!

图 6. 运行消息发送器

此时,消息已由您的 MessageSender 分派,并位于 OpenJMS 管理的队列中,等待被提取。我们不要让它们等待太久,而是编写一个简单的读取器来将它们从队列中取出!

构建消息读取器

按照创建 MessageSender 项目的相同步骤,创建一个名为“MessageGetter”的控制台应用程序,该应用程序将获取消息。请确保添加与该项目相同的引用,即对 OpenJMS jar 的 8 个引用,以及对您之前创建的 System.Messaging 类库的引用。

然后,将与之前在 Class1.cs 顶部添加的“using”指令相同的指令添加到 Class1.cs 的顶部。

最后,这是您的类的 Main 方法。

static void Main(string[] args)
{
  java.util.Hashtable properties = new java.util.Hashtable(); 
  properties.put(Context__Finals.PROVIDER_URL, "tcp://:3035"); 
  properties.put(Context__Finals.INITIAL_CONTEXT_FACTORY, 
              "org.exolab.jms.jndi.InitialContextFactory"); 
  properties.put(Context__Finals.SECURITY_PRINCIPAL, "admin"); 
  properties.put(Context__Finals.SECURITY_CREDENTIALS, "openjms"); 

  string queueServer = "localhost"; 
  string queueName = "queue1"; 


  int N = 10; 
  if (args != null && args.Length > 0) 
  { 
    N = Convert.ToInt32(args[0]); 
  } 
 
  for (int i = 0; i < N; i++) 
  { 
    MessageQueue mq = new MessageQueue("FormatNameIRECT=OS:" + 
                               queueServer + "\\" + queueName); 
 
    System.Messaging.Message theMessage = mq.Receive(); 
    Console.WriteLine("Received message: {0}", theMessage.Body); 
  } 
}

运行此应用程序将为您提供图 7 中的输出。您将看到它接收了发送器发送的每条消息。代码与发送器非常相似。您设置一个 MessageQueue 对象,然后使用 Receive() 方法监听它。这将返回一个消息对象,您可以通过“Body”属性查询其内容。

图 7. 运行消息接收器应用程序。

结论。

Grasshopper 不限于它直接支持的 .NET 命名空间。由于 Java 引用可以直接插入您的应用程序,并且 Java 源代码可以与您的 C# 或 VB.NET 代码内联运行,因此您可以轻松使用外部 Java API。

在本文中,您了解了如何从 Visual Studio.NET 在 OpenJMS 服务器上使用 JMS 消息传递,并看到了将消息发送到队列并从中取出的简单方法。您实现的 System.Messaging 类库可以轻松地在您的应用程序中重用,因此您可以通过 Grasshopper 实现 .NET 应用程序与 JMS 的互操作!

感谢 Laurence Moroney 对本文的润色。

© . All rights reserved.