使用 Ruby 的 Web 服务 - SOAP4R
什么是 SOAP?
简单对象访问协议 (SOAP) 是一种基于 XML 和通常(但不一定)HTTP 的跨平台且与语言无关的 RPC 协议。
它使用 XML 对进行远程过程调用的信息进行编码,并使用 HTTP 将该信息通过网络从客户端传输到服务器,反之亦然。
与 COM、CORBA 等其他技术相比,SOAP 有几个优点:例如,它相对便宜的部署和调试成本、它的可扩展性和易用性,以及针对不同语言和平台的多种实现的存在。
本章让您熟悉 Ruby 的 SOAP 实现(SOAP4R)。 这是一个基础教程,所以如果您需要更深入的细节,您需要参考其他资源。
安装 SOAP4R
SOAP4R 是 Hiroshi Nakamura 为 Ruby 开发的 SOAP 实现,可以从 −
注意 − 您很有可能已经安装了这个组件。
下载 SOAP
如果您知道 gem 实用程序,则可以使用以下命令安装 SOAP4R 和相关软件包。
$ gem install soap4r --include-dependencies
如果您在 Windows 上工作,那么您需要从上述位置下载一个压缩文件,并需要通过运行 ruby install.rb 使用标准安装方法安装它。
编写 SOAP4R 服务器
SOAP4R 支持两种不同类型的服务器 −
- CGI/FastCGI based (SOAP::RPC::CGIStub)
- Standalone (SOAP::RPC:StandaloneServer)
本章详细介绍了编写独立服务器。 编写 SOAP 服务器涉及以下步骤。
第 1 步 - 继承 SOAP::RPC::StandaloneServer 类
要实现您自己的独立服务器,您需要编写一个新类,它将是 SOAP::StandaloneServer 的子类,如下所示 −
class MyServer < SOAP::RPC::StandaloneServer ............... end
注意 − 如果要编写基于 FastCGI 的服务器,则需要将 SOAP::RPC::CGIStub 作为父类,其余过程将保持不变。
第 2 步 - 定义处理程序方法
第二步是编写您希望向外界公开的 Web 服务方法。
它们可以写成简单的 Ruby 方法。 例如,让我们编写两个方法将两个数字相加和两个数字相除 −
class MyServer < SOAP::RPC::StandaloneServer ............... # Handler methods def add(a, b) return a + b end def div(a, b) return a / b end end
第 3 步 - 公开处理程序方法
下一步是将我们定义的方法添加到我们的服务器。 initialize 方法用于通过以下两种方法之一公开服务方法 −
class MyServer < SOAP::RPC::StandaloneServer def initialize(*args) add_method(receiver, methodName, *paramArg) end end
下面是参数说明 −
序号 | 参数 & 说明 |
---|---|
1 | receiver 包含 methodName 方法的对象。 您在与methodDef方法相同的类中定义服务方法,此参数为self。 |
2 | methodName 由于 RPC 请求而调用的方法的名称。 |
3 | paramArg 当给定时,指定参数名称和参数模式。 |
要了解 inout 或 out 参数的用法,请考虑以下服务方法,该方法接受两个参数(inParam 和 inoutParam),返回一个正常返回值(retVal)和两个进一步 参数:inoutParam 和 outParam −
def aMeth(inParam, inoutParam) retVal = inParam + inoutParam outParam = inParam . inoutParam inoutParam = inParam * inoutParam return retVal, inoutParam, outParam end
现在,我们可以如下公开这个方法 −
add_method(self, 'aMeth', [ %w(in inParam), %w(inout inoutParam), %w(out outParam), %w(retval return) ])
第 4 步 - 启动服务器
最后一步是通过实例化派生类的一个实例并调用 start 方法来启动您的服务器。
myServer = MyServer.new('ServerName', 'urn:ruby:ServiceName', hostname, port) myServer.start
这是所需参数的说明 −
序号 | 参数 & 说明 |
---|---|
1 | ServerName 服务器名 |
2 | urn:ruby:ServiceName 这里 urn:ruby 是常量,但您可以为此服务器指定一个唯一的 ServiceName 名称。 |
3 | hostname 指定此服务器将侦听的主机名。 |
4 | port 用于 Web 服务的可用端口号。 |
示例
现在,使用上述步骤,让我们编写一个独立服务器 −
require "soap/rpc/standaloneserver" begin class MyServer < SOAP::RPC::StandaloneServer # Expose our services def initialize(*args) add_method(self, 'add', 'a', 'b') add_method(self, 'div', 'a', 'b') end # Handler methods def add(a, b) return a + b end def div(a, b) return a / b end end server = MyServer.new("MyServer", 'urn:ruby:calculation', 'localhost', 8080) trap('INT){ server.shutdown } server.start rescue => err puts err.message end
执行时,此服务器应用程序在 localhost 上启动一个独立的 SOAP 服务器,并在 port 8080 上侦听请求。它公开了一个服务方法,add 和 div,它接受两个参数并返回结果。
现在,您可以在后台运行此服务器,如下所示 −
$ ruby MyServer.rb&
编写 SOAP4R 客户端
SOAP::RPC::Driver 类支持编写 SOAP 客户端应用程序。 本章描述了这个类,并在一个应用程序的基础上演示了它的用法。
以下是调用 SOAP 服务所需的最基本信息 −
- SOAP 服务的 URL(SOAP 端点 URL)。
- 服务方法的命名空间(方法命名空间 URI)。
- 服务方法的名称及其参数。
现在,我们将编写一个 SOAP 客户端,它会调用上面示例中定义的服务方法,命名为 add 和 div。
以下是创建 SOAP 客户端的主要步骤。
第 1 步 - 创建 SOAP 驱动程序实例
我们通过调用它的新方法来创建 SOAP::RPC::Driver 的实例,如下所示 −
SOAP::RPC::Driver.new(endPoint, nameSpace, soapAction)
这是所需参数的说明 −
序号 | 参数 & 说明 |
---|---|
1 | endPoint 要连接的 SOAP 服务器的 URL。 |
2 | nameSpace 用于通过此 SOAP::RPC::Driver 对象完成的所有 RPC 的命名空间。 |
3 | soapAction HTTP 标头的 SOAPAction 字段的值。 如果为零,则默认为空字符串""。 |
第 2 步 - 添加服务方法
要将 SOAP 服务方法添加到 SOAP::RPC::Driver 我们可以使用 SOAP::RPC::Driver 实例调用以下方法 −
driver.add_method(name, *paramArg)
下面是参数说明 −
序号 | 参数 & 说明 |
---|---|
1 | name 远程 Web 服务方法的名称。 |
2 | paramArg 指定远程过程参数的名称。 |
第 3 步 - 调用 SOAP 服务
最后一步是使用 SOAP::RPC::Driver 实例为 SOAP 服务开票,如下所示 −
result = driver.serviceMethod(paramArg...)
这里 serviceMethod 是实际的 Web 服务方法,paramArg... 是传入服务方法所需的列表参数。
示例
基于以上步骤,我们将编写一个SOAP客户端如下 −
#!/usr/bin/ruby -w require 'soap/rpc/driver' NAMESPACE = 'urn:ruby:calculation' URL = 'http://localhost:8080/' begin driver = SOAP::RPC::Driver.new(URL, NAMESPACE) # Add remote sevice methods driver.add_method('add', 'a', 'b') # Call remote service methods puts driver.add(20, 30) rescue => err puts err.message end
进一步阅读
我已经向您解释了使用 Ruby 的 Web 服务的非常基本的概念。 如果您想进一步深入了解,可以通过以下链接找到有关 使用 Ruby 的 Web 服务 的更多详细信息。