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.
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)
Returns true if there is data in the receive buffer.
-
- (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.
-
- (Object) register_observer(&block)
(also: #on_match)
Register a block to be called when #run_match receives matched data.
-
- (Object) unregister_observer(&block)
Unregister a block from being called when matched data is received.
-
- (Object) 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.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 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 |
# File 'lib/ionian/socket.rb', line 73 def initialize existing_socket = nil, **kwargs, &block @socket = existing_socket @ionian_listeners = [] @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_ary = kwargs.fetch(:host).to_s.split ':' @host = host_port_ary[0] @port = kwargs.fetch :port, host_port_ary[1].to_i || 23 @bind_port = kwargs.fetch :bind_port, @port @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.
15 16 17 |
# File 'lib/ionian/socket.rb', line 15 def bind_port @bind_port end |
- (Object) host (readonly)
IP address or URL of server.
9 10 11 |
# File 'lib/ionian/socket.rb', line 9 def host @host end |
- (Object) port (readonly)
Remote port number.
12 13 14 |
# File 'lib/ionian/socket.rb', line 12 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
19 20 21 |
# File 'lib/ionian/socket.rb', line 19 def protocol @protocol end |
Instance Method Details
- (Boolean) closed?
Returns true if the socket is closed.
222 223 224 225 |
# File 'lib/ionian/socket.rb', line 222 def closed? return true unless @socket @socket.closed? end |
- (Array<MatchData>) cmd(data, **kwargs) {|match| ... }
Send a command (data) to the socket.
179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/ionian/socket.rb', line 179 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.
155 156 157 |
# File 'lib/ionian/socket.rb', line 155 def expression @expression || @socket.expression end |
- (Object) expression=(exp)
Set the regular expression used to match incoming data.
160 161 162 163 |
# File 'lib/ionian/socket.rb', line 160 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.
229 230 231 |
# File 'lib/ionian/socket.rb', line 229 def flush @socket.flush if @persistent end |
- (Boolean) has_data?(**kwargs)
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.
216 217 218 219 |
# File 'lib/ionian/socket.rb', line 216 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.
166 167 168 |
# File 'lib/ionian/socket.rb', line 166 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.
235 236 237 |
# File 'lib/ionian/socket.rb', line 235 def puts *string self.write string.map{ |s| s.chomp }.join("\n") + "\n" end |
- (Object) register_observer(&block) Also known as: on_match
Register a block to be called when #run_match receives matched data. Method callbacks can be registered with &object.method(:method). Returns a reference to the given block. block = ionian_socket.register_observer { … }
195 196 197 198 199 |
# File 'lib/ionian/socket.rb', line 195 def register_observer &block @ionian_listeners << block unless @ionian_listeners.include? block @socket.register_observer &block if @socket block end |
- (Object) unregister_observer(&block)
Unregister a block from being called when matched data is received.
204 205 206 207 208 |
# File 'lib/ionian/socket.rb', line 204 def unregister_observer &block @ionian_listeners.delete_if { |o| o == block } @socket.unregister_observer &block if @socket block end |
- (Object) write(string) Also known as: <<
Writes the given string to the socket. Returns the number of bytes written.
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/ionian/socket.rb', line 241 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 |