Class: Ionian::Socket
- Inherits:
-
Object
- Object
- Ionian::Socket
- Defined in:
- lib/ionian/socket.rb
Overview
A convenient wrapper for TCP, UDP, and Unix client sockets.
Instance Attribute Summary (collapse)
-
- (Object) bind_port
readonly
Local port number.
-
- (Object) host
readonly
IP address or URL of server.
-
- (Object) port
readonly
Remote port number.
-
- (Object) protocol
(also: #protocol?)
readonly
Returns a symbol of the type of protocol this socket uses: :tcp, :udp, :unix.
Class Method Summary (collapse)
-
+ (Ionian::Socket) create_broadcast_socket(**kwargs)
A broadcast socket.
Instance Method Summary (collapse)
-
- (Boolean) closed?
Returns true if the socket is closed.
-
- (Array<MatchData>) cmd(data, **kwargs) {|match| ... }
Send a command (data) to the socket.
-
- (Object) expression
Returns the regular expression used to match incoming data.
-
- (Object) expression=(exp)
Set the regular expression used to match incoming data.
-
- (Object) flush
Flushes buffered data to the operating system.
-
- (Boolean) has_data?(**kwargs)
data until giving up.
-
- (Socket) initialize(existing_socket = nil, **kwargs) {|socket| ... }
constructor
Creates a new socket or wraps an existing socket.
-
- (Boolean) persistent?
Returns true if the socket remains open after writing data.
-
- (Object) puts(*string)
Writes the given string(s) to the socket and appends a newline character to any string not already ending with one.
-
- (Block) register_error_handler {|Exception, self| ... }
(also: #on_error)
Register a block to be called when Extension::IO#run_match raises an error.
-
- (Block) register_match_handler {|MatchData, self| ... }
(also: #on_match)
Register a block to be called when Extension::IO#run_match receives matched data.
-
- (Object) register_observer(&block)
deprecated
Deprecated.
Use #register_match_handler instead.
-
- (Object) unregister_error_handler(&block)
Unregister a block from being called when a IO#run_match error is raised.
-
- (Object) unregister_match_handler(&block)
Unregister a block from being called when matched data is received.
-
- (Object) unregister_observer(&block)
deprecated
Deprecated.
Use #unregister_match_handler instead.
-
- (Fixnum) write(string)
(also: #<<)
Writes the given string to the socket.
Constructor Details
- (Socket) initialize(existing_socket = nil, **kwargs) {|socket| ... }
Creates a new socket or wraps an existing socket.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/ionian/socket.rb', line 88 def initialize existing_socket = nil, **kwargs, &block @socket = existing_socket @ionian_match_handlers = [] @ionian_error_handlers = [] @expression = kwargs.fetch :expression, nil if existing_socket # Convert existing socket. @socket.extend Ionian::Extension::IO @socket.extend Ionian::Extension::Socket if existing_socket.is_a? UNIXSocket @host = existing_socket.path @port = nil else @host = existing_socket.remote_address.ip_address if existing_socket @port = existing_socket.remote_address.ip_port if existing_socket end if @socket.is_a? TCPSocket @protocol = :tcp elsif @socket.is_a? UDPSocket @protocol = :udp elsif @socket.is_a? UNIXSocket @protocol = :unix end @persistent = true # Existing sockets are always persistent. @socket.expression = @expression if @expression initialize_socket_methods else # Initialize new socket. # Parse host out of "host:port" if specified. host_port_array = kwargs.fetch(:host).to_s.split ':' @host = host_port_array[0] @port = kwargs.fetch :port, (host_port_array[1] || 23).to_i @bind_port = kwargs.fetch :bind_port, @port @connect_timeout = kwargs.fetch :connect_timeout, nil @broadcast = kwargs.fetch :broadcast, false # 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? '/' default_protocol = :udp if @broadcast @protocol = kwargs.fetch :protocol, default_protocol @persistent = kwargs.fetch :persistent, true @persistent = true if @protocol == :udp @reuse_addr = kwargs.fetch :reuse_addr, false @cork = kwargs.fetch :cork, false @no_delay = kwargs.fetch :no_delay, @persistent ? false : true # Default to false for persistent sockets, true for # nonpersistent sockets. When nonpersistent, the socket # should remain open to send data in the buffer after # close is called (typically right after write). # @linger = kwargs.fetch :linger, @persistent ? false : true # TODO: For some reason linger = true is causing tests to fail. @linger = kwargs.fetch :linger, false create_socket if @persistent end if block block.call self unless self.closed? self.flush self.close end end end |
Instance Attribute Details
- (Object) bind_port (readonly)
Local port number.
16 17 18 |
# File 'lib/ionian/socket.rb', line 16 def bind_port @bind_port end |
- (Object) host (readonly)
IP address or URL of server.
10 11 12 |
# File 'lib/ionian/socket.rb', line 10 def host @host end |
- (Object) port (readonly)
Remote port number.
13 14 15 |
# File 'lib/ionian/socket.rb', line 13 def port @port end |
- (Object) protocol (readonly) Also known as: protocol?
Returns a symbol of the type of protocol this socket uses: :tcp, :udp, :unix
20 21 22 |
# File 'lib/ionian/socket.rb', line 20 def protocol @protocol end |
Class Method Details
+ (Ionian::Socket) create_broadcast_socket(**kwargs)
Returns a broadcast socket.
29 30 31 32 33 |
# File 'lib/ionian/socket.rb', line 29 def self.create_broadcast_socket **kwargs kwargs[:host] = kwargs.delete(:address) || '255.255.255.255' kwargs[:broadcast] = true new **kwargs end |
Instance Method Details
- (Boolean) closed?
Returns true if the socket is closed.
272 273 274 275 |
# File 'lib/ionian/socket.rb', line 272 def closed? return true unless @socket @socket.closed? end |
- (Array<MatchData>) cmd(data, **kwargs) {|match| ... }
Send a command (data) to the socket.
196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/ionian/socket.rb', line 196 def cmd data, **kwargs, &block create_socket unless @persistent write data @socket.flush matches = @socket.read_match(kwargs) { |match| yield match if block_given? } @socket.close unless @persistent matches end |
- (Object) expression
Returns the regular expression used to match incoming data.
172 173 174 |
# File 'lib/ionian/socket.rb', line 172 def expression @expression || @socket.expression end |
- (Object) expression=(exp)
Set the regular expression used to match incoming data.
177 178 179 180 |
# File 'lib/ionian/socket.rb', line 177 def expression= exp @expression = exp @socket.expression = exp if @socket end |
- (Object) flush
Flushes buffered data to the operating system. This method has no effect on non-persistent sockets.
279 280 281 |
# File 'lib/ionian/socket.rb', line 279 def flush @socket.flush if @persistent end |
- (Boolean) has_data?(**kwargs)
data until giving up. Set to nil for blocking.
266 267 268 269 |
# File 'lib/ionian/socket.rb', line 266 def has_data? **kwargs return false unless @socket @socket.has_data? kwargs end |
- (Boolean) persistent?
Returns true if the socket remains open after writing data.
183 184 185 |
# File 'lib/ionian/socket.rb', line 183 def persistent? @persistent == false || @persistent == nil ? false : true end |
- (Object) puts(*string)
Writes the given string(s) to the socket and appends a newline character to any string not already ending with one.
285 286 287 |
# File 'lib/ionian/socket.rb', line 285 def puts *string self.write string.map{ |s| s.chomp }.join("\n") + "\n" end |
- (Block) register_error_handler {|Exception, self| ... } Also known as: on_error
Register a block to be called when Extension::IO#run_match raises an error. Method callbacks can be registered with &object.method(:method).
245 246 247 248 249 |
# File 'lib/ionian/socket.rb', line 245 def register_error_handler &block @ionian_error_handlers << block unless @ionian_error_handlers.include? block @socket.register_error_handler &block if @socket block end |
- (Block) register_match_handler {|MatchData, self| ... } Also known as: on_match
Register a block to be called when Extension::IO#run_match receives matched data. Method callbacks can be registered with &object.method(:method).
213 214 215 216 217 |
# File 'lib/ionian/socket.rb', line 213 def register_match_handler &block @ionian_match_handlers << block unless @ionian_match_handlers.include? block @socket.register_match_handler &block if @socket block end |
- (Object) register_observer(&block)
Use #register_match_handler instead.
222 223 224 225 |
# File 'lib/ionian/socket.rb', line 222 def register_observer &block STDOUT.puts "WARN: Call to deprecated method #{__method__}" register_match_handler &block end |
- (Object) unregister_error_handler(&block)
Unregister a block from being called when a IO#run_match error is raised.
255 256 257 258 259 |
# File 'lib/ionian/socket.rb', line 255 def unregister_error_handler &block @ionian_error_handlers.delete_if { |o| o == block } @socket.unregister_error_handler &block if @socket block end |
- (Object) unregister_match_handler(&block)
Unregister a block from being called when matched data is received.
228 229 230 231 232 |
# File 'lib/ionian/socket.rb', line 228 def unregister_match_handler &block @ionian_match_handlers.delete_if { |o| o == block } @socket.unregister_match_handler &block if @socket block end |
- (Object) unregister_observer(&block)
Use #unregister_match_handler instead.
235 236 237 238 |
# File 'lib/ionian/socket.rb', line 235 def unregister_observer &block STDOUT.puts "WARN: Call to deprecated method #{__method__}" unregister_match_handler &block end |
- (Fixnum) write(string) Also known as: <<
Writes the given string to the socket.
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/ionian/socket.rb', line 291 def write string create_socket unless @persistent num_bytes = 0 if @protocol == :udp num_bytes = @socket.send string, 0 else num_bytes = @socket.write string end unless @persistent @socket.flush # Read in data to prevent RST packets. # TODO: Shutdown read stream instead? @socket.read_all nonblocking: true # TODO: Sleep added so that data can be read on the receiving # end. Can this be changed to shutdown write? # Why isn't so_linger taking care of this? # sleep 0.01 @socket.close end num_bytes end |