Class: Ionian::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/ionian/server.rb

Overview

A convenient wrapper for TCP, UDP, and Unix server sockets.

Instance Method Summary (collapse)

Constructor Details

- (Server) initialize(**kwargs, &block)

A convenient wrapper for TCP and Unix server sockets (UDP doesn't use a server).

Accepts an optional block that is passed to #register_accept_listener. Server opens listening socket on instantiation if this block is provided.

Args:

interface:      The address of the network interface to bind to.
                Defaults to all.
protocol:       :tcp, :unix. Default is :tcp.


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/ionian/server.rb', line 19

def initialize **kwargs, &block
  @accept_listeners = []
  register_accept_listener &block if block_given?
  
  @interface = kwargs.fetch :interface, ''
  @port      = kwargs.fetch :port, nil
  
  
  # Automatically select UDP for the multicast range. Otherwise default to TCP.
  default_protocol = :tcp
  # TODO: This ivar may be incorrect for UDP -- bound interface is not destination.
  default_protocol = :udp  if Ionian::Extension::Socket.multicast? @interface
  default_protocol = :unix if @interface.start_with? '/'
  
  @protocol  = kwargs.fetch :protocol, default_protocol
  
  # TODO: Move this to #listen.
  case @protocol
  when :tcp
    @server = TCPServer.new @interface, @port
    @server.setsockopt ::Socket::SOL_SOCKET, ::Socket::SO_REUSEADDR, [1].pack('i')
  when :udp
    raise ArgumentError, "UDP should be implemented with Ionian::Socket."
  when :unix
    @server = UNIXServer.new @interface
  end
  
  listen if block_given?
end

Instance Method Details

- (Object) close

Shutdown the server socket and stop listening for connections.



74
75
76
77
78
# File 'lib/ionian/server.rb', line 74

def close
  @server.close if @server
  @accept_thread.join if @accept_thread
  @accept_thread = nil
end

- (Boolean) closed?

Returns true if the server listener socket is closed.

Returns:

  • (Boolean)


81
82
83
# File 'lib/ionian/server.rb', line 81

def closed?
  @server.closed?
end

- (Object) listen(&block)

Starts the socket server listening for connections. Blocks registered with #register_accept_listener will be run when a connection is accepted.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/ionian/server.rb', line 52

def listen &block
  register_accept_listener &block if block_given?
  
  @accept_thread ||= Thread.new do
    # Package in an Ionian::Socket
    begin
      client = Ionian::Socket.new @server.accept
      
      @accept_listeners.each do |listener|
        listener.call client
      end
    rescue Errno::EBADF
      # This ignores the connection if the client closed it before it
      # could be accepted.
    rescue IOError
      # This ignores the connection if the client closed it before it
      # could be accepted.
    end
  end
end

- (Object) register_accept_listener(&block) Also known as: on_accept

Register a block to be run when server accepts a client connection. The connected client is passed to the block as an Ionain::Client.



87
88
89
90
# File 'lib/ionian/server.rb', line 87

def register_accept_listener &block
  @accept_listeners << block unless @accept_listeners.include? block
  block
end

- (Object) unregister_accept_listener(proc)

Unregisters a socket accept notifier block.



95
96
97
98
# File 'lib/ionian/server.rb', line 95

def unregister_accept_listener proc
  @accept_listeners.delete_if {|o| o == proc} 
  proc
end