1

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

我想要的功能如下:

  1. 服务器开始使用对象运行服务客户端。
  2. 客户端连接到服务器,获取对象。
  3. 客户端将它自己的对象返回给服务器。

在不向客户端打开端口(变成服务器)的情况下,这第 3 步是否可行?

问候,

4

1 回答 1

3

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

请参阅此代码:

服务器.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

客户端.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实现了观察者模式,因此您可以使您的服务器可观察,包括DRb::DRbObservable类 Server 中的模块。然后实现notify通知所有观察者的方法,传递可以序列化的对象(包括include DRb::DRbUndumped)。在客户端,我们可以将观察者添加到服务器并实现方法更新来处理通知,请参见以下示例:

服务器.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

客户端.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
于 2016-02-09T20:52:26.393 回答