Ruby DRb 和 Daemon 简单认识和想在一个应用中是否可以使用它们的问题

ruishena · 2015年11月16日 · 最后由 rei 回复于 2015年11月16日 · 1898 次阅读

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)

#--------------------------------------------------------------------------------------------------------------------------------------------------------------

了解 Ruby Daemon 的几个网址:

1.http://stackoverflow.com/questions/3688550/make-a-ruby-program-a-daemon 2.https://github.com/thuehlinger/daemons

#-----项目中的场景-----------------------------------------------------------------------------------

无线手持终端 (WHT)

WHT_A_n ----- Server ----- WHT_B_n 无线手持终端比较简单,wifi+mcu, 基于 HTTP 协议向 Server 发送请求和接收数据。手持终端没有浏览器。

WHT_A 的两个 Action:

1.Connect:请求连接 WHT_B,定时等待 WHT_B 上线。 2.Send:发送 CMD 至 WHT_B,并定时等待 WHT_B 返回 MSG。定时超时则本次 Action 结束。

WHT_B 的两个 Action:

1.Connect:和 Server 保持连接,如果 WHT_A 发送了 CMD 给 WHT_B,则 Server 也通过该接口在 Response body 中反馈给 WHT_B。 2.Close:断开和 Server 的连接

关于 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 中定义.

#-------------------------------------------------------------------------------------------------------------------------------------------------

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册