Simple daemon which can speak and listen

Discussion in 'Ruby' started by Sai Hl, Feb 26, 2009.

  1. Sai Hl

    Sai Hl Guest

    Hi all. According to you, what could be the more sexy way to write a
    simple Ruby daemon (version 1.9 :)) which can speak and listen in the
    same time on a socket (UDP in my case)?

    Thanks,
    Sai
    --
    Posted via http://www.ruby-forum.com/.
    Sai Hl, Feb 26, 2009
    #1
    1. Advertising

  2. sock = UDPSocket.new
    Thread.new do
    sock.write("some string")
    end
    puts sock.read

    However, does it _really_ need to be at the same time? can it not just
    take turns? If you're trying to do two things at the same time on the
    same object, it suggests you need two objects. Just a thought

    Sai Hl wrote:
    > Hi all. According to you, what could be the more sexy way to write a
    > simple Ruby daemon (version 1.9 :)) which can speak and listen in the
    > same time on a socket (UDP in my case)?
    >
    > Thanks,
    > Sai
    >
    Michael Malone, Feb 26, 2009
    #2
    1. Advertising

  3. Sai Hl wrote:
    > Hi all. According to you, what could be the more sexy way to write a
    > simple Ruby daemon (version 1.9 :)) which can speak and listen in the
    > same time on a socket (UDP in my case)?


    More sexy than what - have you written something already? If so, post it
    and we'll look.

    Docs you need:
    http://www.ruby-doc.org/stdlib/libdoc/socket/rdoc/
    http://www.ruby-doc.org/docs/ProgrammingRuby/html/lib_network.html

    The first of these is unfortunately incomplete, e.g. UDPSocket#send is
    missing. However the second has everything you need under the UDPSocket
    header.

    A normal UDP server would typically have a loop where it waits for a
    message, processes it, and then sends back a response to the sender.
    e.g.

    require 'socket'
    sock = UDPSocket.new
    sock.bind(Socket.gethostname, 12345)
    loop do
    packet, sender = sock.recvfrom(1500)
    response = "hello #{packet}"
    sock.send response, 0, sender[3], sender[1]
    end

    Test like this in another window:

    $ irb
    irb(main):001:0> require 'socket'
    => true
    irb(main):002:0> s = UDPSocket.new
    => #<UDPSocket:0xb7d5adec>
    irb(main):003:0> s.connect Socket.gethostname, 12345
    => 0
    irb(main):004:0> s.send "world", 0
    => 5
    irb(main):005:0> s.recvfrom(1500)
    => ["hello world", ["AF_INET", 12345, "example.com", "192.0.2.1"]]

    There's nothing to stop you sending out packets asynchronously on the
    same UDPSocket though, if you want to, and this can even be done in
    another thread.

    So if the processing of one particular packet might take a variable
    amount of time, and you still want to receive and process other packets
    in the mean time, you could do something like this (untested):

    ...
    sock.bind(Socket.gethostname, 12345)
    loop do
    d1, d2 = sock.recvfrom
    Thread.new(d1, d2) do |packet, sender|
    ... process 'packet'
    ... use sock.send to send the response to 'sender'
    end
    end

    Note the use of arguments in Thread.new(...) to pass copies of the local
    variables to the thread. If you used d1 and d2 directly, you'd find that
    they changed as soon as another packet was received in the main loop,
    which leads to some nasty bugs when packets arrive at a fast rate.

    So it's probably safer to write it like this:

    Thread.new(*sock.recvfrom) do |packet, sender|
    ... etc
    end

    Setting Thread.abort_on_exception = true is helpful when debugging this
    sort of code, otherwise when an exception occurs in the thread it just
    dies silently.

    HTH,

    Brian.
    --
    Posted via http://www.ruby-forum.com/.
    Brian Candler, Feb 27, 2009
    #3
  4. On 26 Feb 2009, at 22:15, Sai Hl wrote:
    > Hi all. According to you, what could be the more sexy way to write a
    > simple Ruby daemon (version 1.9 :)) which can speak and listen in the
    > same time on a socket (UDP in my case)?
    >
    > Thanks,
    > Sai


    Follow the link in my sig and you'll find a couple of presentations
    with examples of all kinds of Ruby socket fun, covering both UDP and
    TCP. They also include lots of code which may or may not be fit for
    production purposes :)


    Ellie

    Eleanor McHugh
    Games With Brains
    http://slides.games-with-brains.net
    ----
    raise ArgumentError unless @reality.responds_to? :reason
    Eleanor McHugh, Feb 27, 2009
    #4
  5. Sai Hl

    Sai Hl Guest

    Sai Hl, Feb 27, 2009
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Donny
    Replies:
    13
    Views:
    654
    Donny
    Aug 5, 2004
  2. Jean-Paul Calderone
    Replies:
    0
    Views:
    444
    Jean-Paul Calderone
    Mar 20, 2009
  3. Floris Bruynooghe
    Replies:
    1
    Views:
    439
    Floris Bruynooghe
    Mar 24, 2009
  4. zdennis
    Replies:
    1
    Views:
    137
    Justin Collins
    Aug 11, 2006
  5. Daemon Win32::Daemon;

    , Sep 7, 2006, in forum: Perl Misc
    Replies:
    0
    Views:
    237
Loading...

Share This Page