1

I'm trying to create a simple client-server application. I came across DRuby and I try it out. Seems really nice however I'm not sure if bi-directional communication is allowed.

The functionality that I want is the following:

  1. The server starts running serving client with an object.
  2. Client connects to the server, takes object.
  3. Client returns it's own object to the server.

Is this No3 step possible without opening a port to the client (turning into server) ?

Regards,

patm
  • 1,420
  • 14
  • 19
  • How about a server with multiple clients? – Patrick Oscity Jun 01 '13 at 16:44
  • It should be a server with multiple clients, but I don't understand what do you mean (with the question). It's a server that should have multiple clients... My question is I can do it using DRuby or I have to use another approach i.e. HTTP. – patm Jun 01 '13 at 17:19
  • Sorry that was a stupid comment now that i think of it. Anyway, you will need a connection in every direction i guess. – Patrick Oscity Jun 01 '13 at 17:23
  • Rails 4 supports treating the client/server connection like a file stream, but I don't know what that looks like from the client side of things. – Narfanator Jun 01 '13 at 19:22
  • Rails is an approach that has nothing to do with DRuby though. @padde so if I wanna use a bi-directional connection I need a to open a new connection from the client to the server right? Thanks. – patm Jun 01 '13 at 23:01

1 Answers1

3

You can create an interface in the server, so when the client connects to it, can change some state in the server (pass it's own object).

See this code:

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

the output is:

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

Also, DRuby implements the observer pattern, so you can make your server observable including DRb::DRbObservable module in the class Server. Then you implements the method notify to notify all the observers, passing objects that can be serializes (including include DRb::DRbUndumped). In the client side we can add observer to the server and implement the method update to do something with the notification, see this example:

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

the output is:

{:id=>"from server side"}
{:id=>"from client side"}
checking notifications ...
this is a notification
other notification
leobelizquierdo
  • 1,648
  • 12
  • 20