lib/ionian/socket.rb in ionian-0.6.4 vs lib/ionian/socket.rb in ionian-0.6.5
- old
+ new
@@ -3,10 +3,19 @@
module Ionian
# A convenient wrapper for TCP, UDP, and Unix client sockets.
class Socket
+ # IP address or URL of server.
+ attr_reader :host
+
+ # Remote port number.
+ attr_reader :port
+
+ # Local port number.
+ attr_reader :bind_port
+
# Creates a new socket or wraps an existing socket.
#
# Args:
# host: IP or hostname to connect to.
# port: Connection's port number. Default is 23. Unused by :unix protocol.
@@ -20,11 +29,11 @@
# reuse_addr: Set true to enable the SO_REUSEADDR flag. Allows local address reuse.
# no_delay: Set true to enable the TCP_NODELAY flag. Disables Nagle algorithm.
# cork: Set true to enable the TCP_CORK flag. Buffers multiple writes
# into one segment.
# expression: Overrides the #read_match regular expression for received data.
- def initialize(existing_socket = nil, **kwargs)
+ def initialize existing_socket = nil, **kwargs
@socket = existing_socket
@ionian_listeners = []
@expression = kwargs.fetch :expression, nil
@@ -53,20 +62,21 @@
@persistent = true # Existing sockets are always persistent.
@socket.expression = @expression if @expression
initialize_socket_methods
+
else
# Initialize new socket.
- # TODO: Should be able to parse the port out of host.
- # :port should override this parsed value.
+ # Parse host out of "host:port" if specified.
+ host_port_ary = kwargs.fetch(:host).to_s.split ':'
- @host = kwargs.fetch :host
- @port = kwargs.fetch :port, 23
+ @host = host_port_ary[0]
+ @port = kwargs.fetch :port, host_port_ary[1].to_i || 23
@bind_port = kwargs.fetch :bind_port, @port
-
+
# Automatically select UDP for the multicast range. Otherwise default to TCP.
default_protocol = :tcp
default_protocol = :udp if Ionian::Extension::Socket.multicast? @host
default_protocol = :unix if @host.start_with? '/'
@@ -92,11 +102,11 @@
def expression
@expression || @socket.expression
end
# Set the regular expression used to match incoming data.
- def expression=(exp)
+ def expression= exp
@expression = exp
@socket.expression = exp if @socket
end
# Returns true if the socket remains open after writing data.
@@ -106,22 +116,22 @@
# Send a command (data) to the socket.
# Returns an array of received matches.
# Block yields received match.
# See Ionian::Extension::IO#read_match.
- def cmd(string, **kwargs, &block)
+ def cmd string, **kwargs, &block
create_socket unless @persistent
if @protocol == :udp
@socket.send string, 0
else
@socket.write string
end
@socket.flush
- matches = @socket.read_match(kwargs) {|match| yield match if block_given?}
+ matches = @socket.read_match(kwargs) { |match| yield match if block_given? }
@socket.close unless @persistent
matches
end
@@ -136,23 +146,23 @@
end
alias_method :on_match, :register_observer
# Unregister a block from being called when matched data is received.
- def unregister_observer(&block)
- @ionian_listeners.delete_if {|o| o == block}
+ def unregister_observer &block
+ @ionian_listeners.delete_if { |o| o == block }
@socket.unregister_observer &block if @socket
block
end
### Methods Forwarded To @socket ###
# Returns true if there is data in the receive buffer.
# Args:
# Timeout: Number of seconds to wait for data until
# giving up. Set to nil for blocking.
- def has_data?(**kwargs)
+ def has_data? **kwargs
return false unless @socket
@socket.has_data? kwargs
end
# Returns true if the socket is closed.
@@ -167,17 +177,17 @@
@socket.flush if @persistent
end
# Writes the given string(s) to the socket and appends a
# newline character to any string not already ending with one.
- def puts(*string)
- self.write string.map{|s| s.chomp}.join("\n") + "\n"
+ def puts *string
+ self.write string.map{ |s| s.chomp }.join("\n") + "\n"
end
# Writes the given string to the socket. Returns the number of
# bytes written.
- def write(string)
+ def write string
create_socket unless @persistent
num_bytes = 0
if @protocol == :udp
@@ -253,11 +263,11 @@
# Forward undefined methods to @socket.
# This was chosen over method_missing to avoid traversing the object
# hierarchy on every method call, like transmitting data.
@socket.methods
- .select {|m| @socket.respond_to? m}
- .select {|m| not self.respond_to? m}
+ .select { |m| @socket.respond_to? m }
+ .select { |m| not self.respond_to? m }
.each do |m|
self.singleton_class.send :define_method, m do |*args, &block|
@socket.__send__ m, *args, &block
end
end
\ No newline at end of file