分布式红宝石中的双向通信

时间:2013-06-01 16:22:29

标签: ruby druby

我正在尝试创建一个简单的客户端 - 服务器应用程序。我遇到了DRuby,我试了一下。似乎非常好,但我不确定是否允许双向通信。

我想要的功能如下:

  1. 服务器开始使用对象运行服务客户端。
  2. 客户端连接到服务器,获取对象。
  3. 客户端将自己的对象返回给服务器。
  4. 如果没有打开到客户端的端口(转入服务器),这是否可以执行No3步骤?

    此致

1 个答案:

答案 0 :(得分:2)

您可以在服务器中创建一个接口,因此当客户端连接到它时,可以更改服务器中的某些状态(传递它自己的对象)。

请参阅此代码:

server.rb

require 'drb'

class Server
    attr_accessor :object

    def initialize()
        @object = {:id => 'from server side'}
    end
end

server = Server.new

DRb.start_service('druby://localhost:1992', server)

puts DRb.uri
begin               
    DRb.thread.join
rescue Exception
    Process.kill("TERM", Process.pid)
end

client.rb

require 'drb'
@server = DRbObject.new(nil, "druby://localhost:1992")
DRb.start_service

puts @server.object

@server.object = {:id => "from client side"}

puts @server.object

输出是:

{:id=>"from server side"}
{:id=>"from client side"}

此外,DRuby实现了观察者模式,因此您可以使服务器可观察,包括类Server中的DRb::DRbObservable模块。然后实现方法notify以通知所有观察者,传递可以序列化的对象(包括include DRb::DRbUndumped)。在客户端,我们可以将观察者添加到服务器并实现方法更新以对通知执行某些操作,请参阅此示例:

server.rb

require 'drb'
require 'drb/observer'

class Server
    include DRb::DRbObservable
    attr_accessor :object

    def initialize()
        @object = {:id => 'from server side'}
    end

    def do_something
        notify(Message.new("this is a notification"), Message.new("other notification"))
    end

    def notify(*args)
        changed
        notify_observers(*args)
    end

    class Message
        include DRb::DRbUndumped

        attr_reader :message

        def initialize(message)
            @message = message
        end
    end
end

server = Server.new

DRb.start_service('druby://localhost:1992', server)

puts DRb.uri
begin               
    DRb.thread.join
rescue Exception
    Process.kill("TERM", Process.pid)
end

client.rb

require 'drb'

class MyObserver
    include DRbUndumped

    def update(*notifications)
        puts "checking notifications ..."
        notifications.each do |n|
            puts n.message
        end
    end
end

@server = DRbObject.new(nil, "druby://localhost:1992")
DRb.start_service

@server.add_observer(MyObserver.new)

puts @server.object

@server.object = {:id => "from client side"}

puts @server.object

@server.do_something

输出是:

{:id=>"from server side"}
{:id=>"from client side"}
checking notifications ...
this is a notification
other notification