Ruby分布式对象

最后,我们来看看Ruby中的分布式编程。现在网络已经非常普遍,我们有时候想在网络上传递各种对象,但是不幸的是,像CORBA,RMI这些协议使用起来非常费力,需要特殊规定的编码,异常处理,而且还要在任何调用前定义接口。

Ruby对此有一个简单的解决方法,消除了上面方法的繁琐之处。分布式Ruby(也叫drb或者druby)是一个独立的库,完全由Ruby写成,通过这个库,你可以通过TCP在不同的Ruby进程中传送各种对象(Ruby对象),而且只需要很少的步骤。

清单8显示了这样的一个例子,这个服务端共享了一个对象,通过这个对象,你可以得到服务器的时间。第3行到第7行定义了这个取得本地时间要被共享的对象,第9行将这个对象绑定到一个drb服务器(本例中端口为2222),因为服务器程序在一个独立的线程,所以第10行确保主程序会在这个线程结束后才能退出。

 

清单8: A simple distributed Ruby server

 1   require 'drb'
 2
 3   class Info
 4     def get_time
 5       "It is now #{Time.now}"
 6     end
 7   end
 8
 9   DRb.start_service("druby://your.host.name:2222", Info.new)
10   DRb.thread.join

清单9是一个客户端程序,也非常简单,第4行的DRbObject 调用和远程服务器建立了一个连接,返回了远程对象的一个代理,然后,你就可以像调用本地对象一样调用远程对象的方法了。

 

清单9: A simple distributed Ruby client

 1   require 'drb'
 2
 3   DRb.start_service
 4   info = DRbObject.new(nil, "druby://your.host.name:2222")
 5
 6   3.times do 
 7     puts info.get_time
 8     sleep 2
 9   end
 

 

下面我们来看一下另一个很有意思的东西tuplesapces,它是David Gelernter在Linda系统中首先提出来的,tuplespaces像一个共享的bbs系统,程序可以向它贴消息,或者从它取得消息,这里所说的消息都是一些值组成的数组。out方法用来向tuplespace写消息,所以,下面的代码代码创建了一个含有4条内容的tuplespace:

 

require 'tuplespace'
ts = TupleSpace.new  
ts.out  [ "dave", "car", "blazer" ]
ts.out  [ "dave", "computer", "dell" ]
ts.out  [ "andy", "car", "explorer" ]
ts.out  [ "andy", "os", "linux" ]

使tuplespaces有趣的是你要想取得它里面的内容,你不是根据地址来取,而是根据内容本身(通过匹配)来取。Ruby实现的tuplespace更加强大,取得消息的匹配模式可以是值,对象的类,正则表达式,range等等。nil表示你不关心它的内容是什么,即表示任何东西都匹配nil。要想取得消息内容可以用in方法,如果in方法中指定的模式能在tuplespace中找到匹配的项,那么这个匹配的项将被从tuplespace中删除,并且将这项返回给调用者;否则的话,in将等待直到有匹配的项目出现。如果有多个记录匹配in中指定的模式,那么将会随机的返回其中的一个记录。

继续前面的例子,下面的例子从tuplespace中读取已经存入的记录,注意最后一个语句,它使用了正则表达式作为匹配的模式。

# read one of Dave's possessions
res1 = ts.in ["dave", nil, nil]
# someone owning a car
res2 = ts.in [nil, "car", nil]
# a possession containing the "x" or "z"
res3 = ts.in [nil, nil, /[xz]/]

从这个简单的例子开始,你能轻松地编写出复杂,协作,并行的系统。

比如,你可以用tuplespace解决复杂地AI问题。一个进程可以通过将一组数据组合起来放到tuplespace中来产生一个问题,其他进程则通过匹配地方式从tuplespace中读取它能解决地问题;一个进程得到一个错误地时候,它也可能把这个问题细分为更小的问题 ,然后将它们放到tuplespace里面。其它的进程又取得这个问题,然后解决它们或者继续分解这些问题。

这个过程将继续,直到所有的问题都得到解决。

为了完成这篇文章,我们将使用drb和tuplespace编写一个简单的P2P的聊天程序,这个系统将由三个元素组成的消息存放在tuplespace中,即消息的发送者,接收者,和消息内容。

客户端的程序在清单10中,客户端由两个线程一起运行,发送线程是主线程,在它里面显示的创建了接收线程。发送线程从第16行到22行,它从用户的控制台读取字符串,格式如下:

to:  message text

to是接收者姓名,第17行将上面的输入分成两部分,前面的是姓名,剩下的是消息内容。然后,第19行将这个消息组成一个数组写到tuplespace里面。

 

清单10: A chat client based on tuplespaces

 1   require 'drb'
 2   require 'tuplespace'
 3
 4   DRb.start_service
 5   ts = DRbObject.new(nil, / "druby://server.host:12321")
 6
 7   my_name = ARGV[0]
 8
 9   Thread.new do
10     loop do
11       from, unused, line = ts.in / [ nil, my_name, nil ]
12       puts "#{from} says: #{line}"
13     end
14   end
15
16   while line = gets
17     to, text = line.split(/:/, 2)
18     if text
19       ts.out [ my_name, to, text ]
20     else
21       puts '** use   "to: message"'
22     end
23   end

接收线程也很简单,第9行到14行运行一个简单的循环,从tuplespace中读取数据,匹配条件是消息接收者是我们自己的名字,然后将结果打印在控制台上。

 

Tuplespaces需要一个服务器存放tuples,在Ruby中用drb服务器来存放tuplespace对象,可以用下面代码实现:

require 'drb'
require 'tuplespace'
DRb.start_service("druby://server.host:12321", / 
  TupleSpace.new)
DRb.thread.join

首先运行服务端程序,然后运行客户端,并且在客户端程序指定你想用的名字作为参数。

如果你运行它你会发现,如果你不在线,服务器端会把给你的消息保存在服务器上。我们的这个应用程序不恩那个取代Yahoo IM,Jabber或者IRC等,但这段代码却非常有用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值