Drb 的一个例子:假设我们有一个 Counter Object 对象,并且在网络上共享,就好像记录访问网站的人数。对 Counter Object 可以做两件事:每次增加它的值 (+1)+读取它的值。 关于介绍 DRb 的几个网址: 1.http://ruby-doc.org/stdlib-1.9.3/libdoc/drb/rdoc/DRb.html DRuby 使用纯 Ruby 打造。看到这句 uses its own protocol,作为小白先只要能学会用就差不多了。Drb 允许在一个 Ruby 进程中的方法调用另一个 Ruby 进程中的对象,该对象甚至可以不在本地,在另一台机器上。该对象的引用可以在 processes 中相互传递。对于方法中的参数和返回值,介绍中说 they are dumped and loaded in marshalled format.(DRb::DRbUndumped---http://ruby-doc.org/stdlib-1.9.3/libdoc/drb/rdoc/DRb/DRbServer.htmlmake介绍中说 an object undumpable or unmarshllable,关于这几个单词 dumped,marshalled,undumpable, unmarshllable 不知道怎么理解---丢弃,包装好的,未被丢弃的,未被包装的?) 这些对于远程方法的调用者和相关的对象都是透明的。
一个远程进程上的对象在本地以 DRb:DRbObject 实例方式而存在,即一种远程对象的代理。在该 DRbObject 对象上调用的方法,会传递到远程的对象上。 DRb 中一个非常重要的对象是 DRb:DRbServer,它重建方法调用,在本地指定的对象上调用某方法,并向远程调用者返回结果。任何对象通过 DRb 都能接收类似的远程调用。在一般情况下,一个对象想要得到远程的调用需要显示地通过 DRb:DRbServer 注册自己。假设 Server 上有个 Class Count,然后 Client 上想要调用 Class Count 里的方法。DRbServer 绑定 URI 后,Client 可以通过 DRbServer.new_with_uri 方法获取该对象的引用,then the client can do whatever it wants with the Count.而依附在 Server 上的 Class Count 被称作 front object。 #######Server#########################
#!/usr/bin/env ruby
require 'drb'
class Counter
attr_reader :value
def initialize
@value = 0
end
def increment
@value += 1
end
end
DRb.start_service 'druby://localhost:9000', Counter.new
puts "Server running at #{DRb.uri}"
DRb.thread.join
Server 端定义了一个 Count 计数器类,DRb.start_service(uri,front,config),这里 URI(druby://:) 是定义在本地的 9000 端口,Counter.new 即为之前提过的 front object,the object to which remote method calls on the server will be passed. config 参数在这里为空。然后通过 DRb.thread.join 加入 DRb thread。服务端究竟做了什么呢? 它实际上开启了一个 socket,然后监听请求,返回该 Count 类的引用。At that point, the client can do whatever it wants with the Count。 执行 ruby Server.rb 后,会看到打印出 Server 的端口,如果按下 ctrl+c 会终止 Server thread. #########Client##################################
require 'drb'
DRb.start_service
counterObj= DRbObject.new_with_uri 'druby://localhost:9000'
counterObj.increment
puts "The counter value is #{counterObj.value}"
在 Client 端,DRbObject.new_with_uri(uri) --->Create a new DRbObject from a URI alone. 终端运行 ruby Client.rb 后,会打印出 counter 的值,每执行一次,count 的值 +1.
2.http://ruby.about.com/od/advancedruby/a/drb.htm ---- An Intrduction to to Distributed Ruby. 3.http://blog.csdn.net/heiyeshuwu/article/details/1149885 ---Introduction to Distributed Ruby (DRb)
#--------------------------------------------------------------------------------------------------------------------------------------------------------------
1.http://stackoverflow.com/questions/3688550/make-a-ruby-program-a-daemon 2.https://github.com/thuehlinger/daemons
#-----项目中的场景-----------------------------------------------------------------------------------
WHT_A_n ----- Server ----- WHT_B_n 无线手持终端比较简单,wifi+mcu, 基于 HTTP 协议向 Server 发送请求和接收数据。手持终端没有浏览器。
1.Connect:请求连接 WHT_B,定时等待 WHT_B 上线。 2.Send:发送 CMD 至 WHT_B,并定时等待 WHT_B 返回 MSG。定时超时则本次 Action 结束。
1.Connect:和 Server 保持连接,如果 WHT_A 发送了 CMD 给 WHT_B,则 Server 也通过该接口在 Response body 中反馈给 WHT_B。 2.Close:断开和 Server 的连接
1.使用 require daemons 和 require drb
2.运行一个后台进程监听 WTH_A 和 WTH_B 请求,
Class ListenObj
...funcation
end
Daemons.run_proc 'drbServer.rb' do
$SAFE=1
DRb.start_service 'druby://localhost:8099', ListenObj.new
DRb.thread.join
end
3.在 ROR 的 Controller 中,定义 WTH_A 和 WTH_B 的 connect,send,close 相关 Action,Action 中调用 ListenObj 里的方法;如判断 WTH_B 是否在线,WTH_A 是否发送 CMD 至 WTH_B_id
DRb.start_service
listenObj=DRbObject.new_with_uri druby://localhost:8099
if listenObj.xxx_funcation ?
.....
end
4.请求到达时:提取 HTTP Request Head 里面的 URL 部分参数信息和 Request body 信息,提取方法在 Class ListenObj 中定义。
#-------------------------------------------------------------------------------------------------------------------------------------------------