Ruby_09_网络编程




Ruby 发送邮件 - SMATP

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。

Ruby提供了 Net::SMTP 来发送邮件,并提供了两个方法 new 和 start:

  • new 方法有两个参数:
    • server name 默认为 localhost
    • port number 默认为 25
  • start 方法有以下参数:
    • server - SMTP 服务器 IP, 默认为 localhost
    • port - 端口号,默认为 25
    • domain - 邮件发送者域名,默认为 ENV["HOSTNAME"]
    • account - 用户名,默认为 nil
    • password - 用户密码,默认为nil
    • authtype - 验证类型,默认为 cram_md5

SMTP 对象实例化方法调用了 sendmail, 参数如下:

  • source - 一个字符串或数组或每个迭代器在任一时间中返回的任何东西。
  • sender -一个字符串,出现在 email 的表单字段。
  • recipients - 一个字符串或字符串数组,表示收件人的地址。

实例

以下提供了简单的Ruby脚本来发送邮件:

require 'net/smtp'

message = <<MESSAGE_END From: Private Person <me@fromdomain.com>
To: A Test User <test@todomain.com>
Subject: SMTP e-mail test

This is a test e-mail message.
MESSAGE_END

Net::SMTP.start('localhost') do |smtp|
  smtp.send_message message, 'me@fromdomain.com', 
                             'test@todomain.com'
end

在以上实例中,你已经设置了一个基本的电子邮件消息,注意正确的标题格式。一个电子邮件要要From,To和Subject,文本内容与头部信息间需要一个空行。

使用Net::SMTP连接到本地机器上的SMTP服务器,使用send_message方法来发送邮件,方法参数为发送者邮件与接收者邮件。

如果你没有运行在本机上的SMTP服务器,您可以使用Net::SMTP与远程SMTP服务器进行通信。如果使用网络邮件服务(如Hotmail或雅虎邮件),您的电子邮件提供者会为您提供发送邮件服务器的详细信息:

Net::SMTP.start('mail.your-domain.com')

以上代码将连接主机为 mail.your-domain.com,端口号为 25的邮件服务器,如果需要填写用户名密码,则代码如下:

Net::SMTP.start('mail.your-domain.com', 
                25, 
                'localhost', 
                'username', 'password' :plain)

以上实例使用了指定的用户名密码连接到主机为 mail.your-domain.com,端口号为 25的邮件服务器。


使用 Ruby 发送 HTML 邮件

Net::SMTP同样提供了支持发送 HTML 格式的邮件。

发送电子邮件时你可以设置MIME版本,文档类型,字符集来发送HTML格式的邮件。

实例

以下实例用于发送 HTML 格式的邮件:

require 'net/smtp'

message = <<MESSAGE_END From: Private Person <me@fromdomain.com>
To: A Test User <test@todomain.com>
MIME-Version: 1.0
Content-type: text/html
Subject: SMTP e-mail test

This is an e-mail message to be sent in HTML format

<b>This is HTML message.</b>
<h1>This is headline.</h1>
MESSAGE_END

Net::SMTP.start('localhost') do |smtp|
  smtp.send_message message, 'me@fromdomain.com', 
                             'test@todomain.com'
end

发送带附件的邮件

如果需要发送混合内容的电子邮件,需要设置Content-type为multipart/mixed。 这样就可以在邮件中添加附件内容。

附件在传输前需要使用 pack("m") 函数将其内容转为 base64 格式。

实例

以下实例将发送附件为 /tmp/test.txt 的邮件:

require 'net/smtp'

filename = "/tmp/test.txt"
# 读取文件并编码为base64格式
filecontent = File.read(filename)
encodedcontent = [filecontent].pack("m")   # base64

marker = "AUNIQUEMARKER"

body =<<EOF
This is a test email to send an attachement.
EOF

# 定义主要的头部信息
part1 =<<EOF
From: Private Person <me@fromdomain.net>
To: A Test User <test@todmain.com>
Subject: Sending Attachement
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=#{marker}
--#{marker}
EOF

# 定义消息动作
part2 =<<EOF
Content-Type: text/plain
Content-Transfer-Encoding:8bit

#{body}
--#{marker}
EOF

# 定义附件部分
part3 =<<EOF
Content-Type: multipart/mixed; name=\"#{filename}\"
Content-Transfer-Encoding:base64
Content-Disposition: attachment; filename="#{filename}"

#{encodedcontent}
--#{marker}--
EOF

mailtext = part1 + part2 + part3

# 发送邮件
begin 
  Net::SMTP.start('localhost') do |smtp|
     smtp.sendmail(mailtext, 'me@fromdomain.net',
                          ['test@todmain.com'])
  end
rescue Exception => e  
  print "Exception occured: " + e  
end  

注意:你可以指定多个发送的地址,但需要使用逗号隔开。


Ruby Socket 编程

Ruby提供了两个级别访问网络的服务,在底层你可以访问操作系统,它可以让你实现客户端和服务器为面向连接和无连接协议的基本套接字支持。

Ruby 统一支持应用程的网络协议,如FTP、HTTP等。

不管是高层的还是底层的。ruby提供了一些基本类,让你可以使用TCP,UDP,SOCKS等很多协议交互,而不必拘泥在网络层。这些类也提供了辅助类,让你可以轻松的对服务器进行读写。

接下来就让我们来学习如何进行 Ruby Socket 编程


什么是 Sockets

应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要 通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字 (Socket)的接口,区分不同应用程序进程间的网络通信和连接。

生成套接字,主要有3个参数:通信的目的IP地址、使用的传输 层协议(TCP或UDP)和使用的端口号。Socket原意是"插座"。通过将这3个参数结合起来,与一个"插座"Socket绑定,应用层就可以和传输 层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

Sockets 词汇解析:

选项描述
domain指明所使用的协议族,通常为 PF_INET, PF_UNIX, PF_X25, 等等。
type指定socket的类型:SOCK_STREAM 或SOCK_DGRAM,Socket接口还定义了原始Socket(SOCK_RAW),允许程序使用低层协议
protocol通常赋值0。
hostname网络接口的标识符:
  • 字符串, 可以是主机名或IP地址
  • 字符串 "<broadcast>", 指定 INADDR_BROADCAST 地址。
  • 0 长度的字符串, 指定INADDR_ANY
  • 一个整数,解释为主机字节顺序的二进制地址。
portport是端口的编号,每个服务器都会监听客户端连接的一个或多个端口号,一个端口号可以是 Fixnum 的端口号, 包含了服务器名和端口。

简单的客户端

以下我们通过给定的主机和端口编写了一个简单的客户端实例,Ruby TCPSocket 类提供了 open 方法来打开一个 socke。

TCPSocket.open(hosname, port ) 打开一个 TCP 连接。

一旦你打开一个 Socket 连接,你可以像 IO 对象一样读取它,完成后,你需要像关闭文件一样关闭该连接。

以下实例演示了如何连接到一个指定的主机,并从 socket 中读取数据,最后关闭socket:

require 'socket'      # Sockets 是标准库

hostname = 'localhost'
port = 2000

s = TCPSocket.open(hostname, port)

while line = s.gets   # 从 socket 中读取每行数据
  puts line.chop      # 打印到终端
end
s.close               # 关闭 socket 

简单的服务

Ruby 中可以使用 TCPServer 类来写个简单的服务。TCPServer 对象是 TCPSocket 的工厂对象。

现在我们使用 TCPServer.open(hostname, port) 来创建一个 TCPServer 对象。

接下来调用 TCPServer 的 accept 方法,该方法会等到一个客户端连接到指定的端口,然后返回一个的TCPSocket对象,表示连接到该客户端。

require 'socket'               # 获取socket标准库

server = TCPServer.open(2000)  # Socket 监听端口为 2000
loop {                         # 永久运行服务
  client = server.accept       # 等待客户端连接
  client.puts(Time.now.ctime)  # 发送时间到客户端
  client.puts "Closing the connection. Bye!"
  client.close                 # 关闭客户端连接
}

现在,在服务器上运行以上代码,查看效果。


多客户端TCP服务

互联网上,大多服务都有大量的客户端连接。

Ruby的Thread类可以很容易地创建多线程服务,一个线程执行客户端的连接,而主线程在等待更多的连接。

require 'socket'                # 获取socket标准库

server = TCPServer.open(2000)   # Socket 监听端口为 2000
loop {                          # 永久运行服务
  Thread.start(server.accept) do |client|
    client.puts(Time.now.ctime) # 发送时间到客户端
 client.puts "Closing the connection. Bye!"
    client.close                # 关闭客户端连接
  end
}

在这个例子中,socket永久运行,而当server.accept接收到客户端的连接时,一个新的线程被创建并立即开始处理请求。而主程序立即循环回,并等待新的连接。


微小的Web浏览器

我们可以使用socket库来实现任何的 Internet 协议。以下代码展示了如何获取网页的内容:

require 'socket'
 
host = 'www.w3cschool.cn'     # web服务器
port = 80                           # 默认 HTTP 端口
path = "/index.htm"                 # 想要获取的文件地址

# 这是个 HTTP 请求
request = "GET #{path} HTTP/1.0\r\n\r\n"

socket = TCPSocket.open(host,port)  # 连接服务器
socket.print(request)               # 发送请求
response = socket.read              # 读取完整的响应
# Split response at first blank line into headers and body
headers,body = response.split("\r\n\r\n", 2) 
print body                          # 输出结果

要实现一个类似 web 的客户端,你可以使用为 HTTP 预先构建的库如Net::HTTP。

以下代码与先前代码是等效的:

require 'net/http'                  # 我们需要的库
host = 'www.w3cschool.cn'           #  web 服务器
path = '/index.htm'                 # 我们想要的文件 

http = Net::HTTP.new(host)          # 创建连接
headers, body = http.get(path)      # 请求文件
if headers.code == "200"            # 检测状态码
  print body                        
else                                
  puts "#{headers.code} #{headers.message}" 
end



Ruby JSON

本章节我们将为大家介绍如何使用 Ruby 语言来编码和解码 JSON 对象。


环境配置

在使用 Ruby 编码或解码 JSON 数据前,我们需要先安装 Ruby JSON 模块。在安装该模块前你需要先安装 Ruby gem,我们使用 Ruby gem 安装 JSON 模块。 但是,如果你使用的是最新版本的 Ruby,可能已经安装了 gem,解析来我们就可以使用以下命令来安装Ruby JSON 模块:

$gem install json

使用 Ruby 解析 JSON

以下为JSON数据,将该数据存储在 input.json 文件中:

{
  "President": "Alan Isaac",
  "CEO": "David Richardson",
  
  "India": [
    "Sachin Tendulkar",
    "Virender Sehwag",
    "Gautam Gambhir",
  ],

  "Srilanka": [
    "Lasith Malinga",
    "Angelo Mathews",
    "Kumar Sangakkara"
  ],

  "England": [
    "Alastair Cook",
    "Jonathan Trott",
    "Kevin Pietersen"
  ]
}

以下的 Ruby 程序用于解析以上 JSON 文件;

#!/usr/bin/ruby
require 'rubygems'
require 'json'
require 'pp'

json = File.read('input.json')
obj = JSON.parse(json)

pp obj

以上实例执行结果为:

{"President"=>"Alan Isaac",
 "CEO"=>"David Richardson",

 "India"=>
  ["Sachin Tendulkar", "Virender Sehwag", "Gautam Gambhir"],

"Srilanka"=>
  ["Lasith Malinga ", "Angelo Mathews", "Kumar Sangakkara"],

 "England"=>
  ["Alastair Cook", "Jonathan Trott", "Kevin Pietersen"]
}


Ruby XML, XSLT 和 XPath 教程


什么是 XML ?

XML 指可扩展标记语言(eXtensible Markup Language)。

可扩展标记语言,标准通用标记语言的子集,一种用于标记电子文件使其具有结构性的标记语言。

它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。


XML解析器结构和API

XML的解析器主要有DOM和SAX两种。

  • SAX解析器是基于事件处理的,需要从头到尾把XML文档扫描一遍,在扫描的过程中,每次遇到一个语法结构时,就会调用这个特定语法结构的事件处理程序,向应用程序发送一个事件。
  • DOM是文档对象模型解析,构建文档的分层语法结构,在内存中建立DOM树,DOM树的节点以对象的形式来标识,文档解析文成以后,文档的整个DOM树都会放在内存中。

Ruby 中解析及创建 XML

RUBY中对XML的文档的解析可以使用这个库REXML库。

REXML库是ruby的一个XML工具包,是使用纯Ruby语言编写的,遵守XML1.0规范。

在Ruby1.8版本及其以后,RUBY标准库中将包含REXML。

REXML库的路径是: rexml/document

所有的方法和类都被封装到一个REXML模块内。

REXML解析器比其他的解析器有以下优点:

  • 100% 由 Ruby 编写。
  • 可适用于 SAX 和 DOM 解析器。
  • 它是轻量级的,不到2000行代码。
  • 很容易理解的方法和类。
  • 基于 SAX2 API 和完整的 XPath 支持。
  • 使用 Ruby 安装,而无需单独安装。

以下为实例的 XML 代码,保存为movies.xml:

<collection shelf="New Arrivals">
<movie title="Enemy Behind">
   <type>War, Thriller</type>
   <format>DVD</format>
   <year>2003</year>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Talk about a US-Japan war</description>
</movie>
<movie title="Transformers">
   <type>Anime, Science Fiction</type>
   <format>DVD</format>
   <year>1989</year>
   <rating>R</rating>
   <stars>8</stars>
   <description>A schientific fiction</description>
</movie>
   <movie title="Trigun">
   <type>Anime, Action</type>
   <format>DVD</format>
   <episodes>4</episodes>
   <rating>PG</rating>
   <stars>10</stars>
   <description>Vash the Stampede!</description>
</movie>
<movie title="Ishtar">
   <type>Comedy</type>
   <format>VHS</format>
   <rating>PG</rating>
   <stars>2</stars>
   <description>Viewable boredom</description>
</movie>
</collection>

DOM 解析器

让我们先来解析 XML 数据,首先我们先引入 rexml/document 库,通常我们可以将 REXML 在顶级的命名空间中引入:

#!/usr/bin/ruby -w

require 'rexml/document'
include REXML

xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)

# 获取 root 元素
root = xmldoc.root
puts "Root element : " + root.attributes["shelf"]

# 以下将输出电影标题
xmldoc.elements.each("collection/movie"){ 
   |e| puts "Movie Title : " + e.attributes["title"] 
}

# 以下将输出所有电影类型
xmldoc.elements.each("collection/movie/type") {
   |e| puts "Movie Type : " + e.text 
}

# 以下将输出所有电影描述
xmldoc.elements.each("collection/movie/description") {
   |e| puts "Movie Description : " + e.text 
}

以上实例输出结果为:

Root element : New Arrivals
Movie Title : Enemy Behind
Movie Title : Transformers
Movie Title : Trigun
Movie Title : Ishtar
Movie Type : War, Thriller
Movie Type : Anime, Science Fiction
Movie Type : Anime, Action
Movie Type : Comedy
Movie Description : Talk about a US-Japan war
Movie Description : A schientific fiction
Movie Description : Vash the Stampede!
Movie Description : Viewable boredom
SAX-like Parsing:

SAX 解析器

处理相同的数据文件:movies.xml,不建议SAX的解析为一个小文件,以下是个简单的实例:

#!/usr/bin/ruby -w

require 'rexml/document'
require 'rexml/streamlistener'
include REXML


class MyListener
  include REXML::StreamListener
  def tag_start(*args)
    puts "tag_start: #{args.map {|x| x.inspect}.join(', ')}"
  end

  def text(data)
    return if data =~ /^\w*$/     # whitespace only
    abbrev = data[0..40] + (data.length > 40 ? "..." : "")
    puts "  text   :   #{abbrev.inspect}"
  end
end

list = MyListener.new
xmlfile = File.new("movies.xml")
Document.parse_stream(xmlfile, list)

以上输出结果为:

tag_start: "collection", {"shelf"=>"New Arrivals"}
tag_start: "movie", {"title"=>"Enemy Behind"}
tag_start: "type", {}
  text   :   "War, Thriller"
tag_start: "format", {}
tag_start: "year", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
  text   :   "Talk about a US-Japan war"
tag_start: "movie", {"title"=>"Transformers"}
tag_start: "type", {}
  text   :   "Anime, Science Fiction"
tag_start: "format", {}
tag_start: "year", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
  text   :   "A schientific fiction"
tag_start: "movie", {"title"=>"Trigun"}
tag_start: "type", {}
  text   :   "Anime, Action"
tag_start: "format", {}
tag_start: "episodes", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
  text   :   "Vash the Stampede!"
tag_start: "movie", {"title"=>"Ishtar"}
tag_start: "type", {}
tag_start: "format", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
  text   :   "Viewable boredom"

XPath 和 Ruby

我们可以使用XPath来查看XML ,XPath 是一门在 XML 文档中查找信息的语言(查看:XPath 教程)。

XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言。XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。

Ruby 通过 REXML 的 XPath 类支持 XPath,它是基于树的分析(文档对象模型)。

#!/usr/bin/ruby -w

require 'rexml/document'
include REXML

xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)

# 第一个电影的信息
movie = XPath.first(xmldoc, "//movie")
p movie

# 打印所有电影类型
XPath.each(xmldoc, "//type") { |e| puts e.text }

# 获取所有电影格式的类型,返回数组
names = XPath.match(xmldoc, "//format").map {|x| x.text }
p names

以上实例输出结果为:

<movie title='Enemy Behind'> ... </>
War, Thriller
Anime, Science Fiction
Anime, Action
Comedy
["DVD", "DVD", "DVD", "VHS"]

XSLT 和 Ruby

Ruby 中有两个 XSLT 解析器,以下给出简要描述:

Ruby-Sablotron

这个解析器是由正义Masayoshi Takahash编写和维护。这主要是为Linux操作系统编写的,需要以下库:

  • Sablot
  • Iconv
  • Expat

XSLT4R

XSLT4R 由 Michael Neumann 编写。 XSLT4R 用于简单的命令行交互,可以被第三方应用程序用来转换XML文档。

XSLT4R需要XMLScan操作,包含了 XSLT4R 归档,它是一个100%的Ruby的模块。这些模块可以使用标准的Ruby安装方法(即Ruby install.rb)进行安装。

XSLT4R 语法格式如下:

ruby xslt.rb stylesheet.xsl document.xml [arguments]

如果您想在应用程序中使用XSLT4R,您可以引入XSLT及输入你所需要的参数。实例如下:

require "xslt"

stylesheet = File.readlines("stylesheet.xsl").to_s
xml_doc = File.readlines("document.xml").to_s
arguments = { 'image_dir' => '/....' }

sheet = XSLT::Stylesheet.new( stylesheet, arguments )

# output to StdOut
sheet.apply( xml_doc )

# output to 'str'
str = ""
sheet.output = [ str ]
sheet.apply( xml_doc )

 

Ruby Web Services 应用 - SOAP4R


什么是 SOAP?

简单对象访问协议(SOAP,全写为Simple Object Access Protocol)是交换数据的一种协议规范。

SOAP 是一种简单的基于 XML 的协议,它使应用程序通过 HTTP 来交换信息。

简单对象访问协议是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息。



SOAP4R 安装

SOAP4R 由Hiroshi Nakamura开发实现,用于 Ruby 的 SOAP 应用。

SOAP4R 下载地址:http://raa.ruby-lang.org/soap4r/

注意:你的ruby环境可能已经安装了该该组件。

Linux 环境下你也可以使用 gem 来安装该组件,命令如下:

$ gem install soap4r --include-dependencies

如果你是window环境下开发,你需要下载zip压缩文件,并通过执行 install.rb 来安装。


SOAP4R 服务

SOAP4R 支持两种不同的服务类型:

  • 基于 CGI/FastCGI 服务 (SOAP::RPC::CGIStub)
  • 独立服务 (SOAP::RPC:StandaloneServer)

本教程将为大家介绍如何建立独立的 SOAP 服务。步骤如下:

第1步 - 继承SOAP::RPC::StandaloneServer

为了实现自己的独立的服务器,你需要编写一个新的类,该类为 SOAP::RPC::StandaloneServer 的子类:

class MyServer < SOAP::RPC::StandaloneServer   ............... end 

注意:如果你要编写一个基于FastCGI的服务器,那么你需要继承 SOAP::RPC::CGIStub 类,程序的其余部分将保持不变。

第二步 - 定义处理方法

接下来我们定义Web Services的方法,如下我们定义两个方法,一个是两个数相加,一个是两个数相除:

class MyServer < SOAP::RPC::StandaloneServer
   ...............

   # 处理方法
   def add(a, b)
      return a + b
   end
   def div(a, b) 
      return a / b 
   end
end

第三步 - 公布处理方法

接下来添加我们在服务器上定义的方法,initialize方法是公开的,用于外部的连接:

class MyServer < SOAP::RPC::StandaloneServer
   def initialize(*args)
      add_method(receiver, methodName, *paramArg)
   end
end

以下是各参数的说明:

参数描述
receiver包含方法名的方法的对象。 如果你在同一个类中定义服务方法,该参数为 self。
methodName调用 RPC 请求的方法名。
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)
])

第四步 - 开启服务

最后我们通过实例化派生类,并调用 start 方法来启动服务:

myServer = MyServer.new('ServerName',
                        'urn:ruby:ServiceName', hostname, port)

myServer.start

以下是请求参数的说明:

参数描述
ServerName服务名,你可以取你喜欢的
urn:ruby:ServiceNameHere urn:ruby 是固定的,但是你可以为你的服务取一个唯一的 ServiceName
hostname指定主机名
portweb 服务端口

实例

接下来我们通过以上的步骤,创建一个独立的服务:

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

执行以上程序后,就启动了一个监听 8080 端口的本地服务,并公开两个方法:add 和 div。

你可以再后台执行以上服务:

$ ruby MyServer.rb&

SOAP4R 客户端

ruby 中使用 SOAP::RPC::Driver 类开发 SOAP 客户端。接下来我们来详细看下 SOAP::RPC::Driver 类的使用。

调用 SOAP 服务需要以下信息:

  • SOAP 服务 URL 地址 (SOAP Endpoint URL)
  • 服务方法的命名空间(Method Namespace URI)
  • 服务方法名及参数信息

接下来我们就一步步来创建 SOAP 客户端来调用以上的 SOAP 方法:add 、 div:

第一步 - 创建 SOAP Driver 实例

我们可以通过实例化 SOAP::RPC::Driver 类来调用它的新方法,如下所示:

SOAP::RPC::Driver.new(endPoint, nameSpace, soapAction)

以下是参数的描述:

参数描述
endPoint连接 SOAP 服务的 URL 地址
nameSpace命名空间用于 SOAP::RPC::Driver 对象的所有 RPC .
soapAction用于 HTTP 头部的 SOAPAction 字段值。如果是字符串是"" 则默认为 nil

第二步 - 添加服务方法

为 SOAP::RPC::Driver 添加 SOAP 服务方法,我们可以通过实例 SOAP::RPC::Driver 来调用以下方法:

driver.add_method(name, *paramArg)

以下是参数的说明:

参数描述
name远程web服务的方法名
paramArg指定远程程序的参数

第三步 - 调用SOAP服务

最后我们可以使用 SOAP::RPC::Driver 实例来调用 SOAP 服务:

result = driver.serviceMethod(paramArg...)

serviceMethod SOAP服务的实际方法名,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

 



未完待续,下一章节,つづく



转载于:https://www.cnblogs.com/ixixii/p/8481533.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值