Class: TCPSocket

Inherits:
IPSocket show all
Defined in:
lib/polyphony/extensions/socket.rb

Overview

Overide stock TCPSocket code by encapsulating a Socket instance

Direct Known Subclasses

TCPServer

Instance Method Summary collapse

Constructor Details

#initialize(remote_host, remote_port, local_host = nil, local_port = nil) ⇒ TCPSocket

Initializes the socket.

Parameters:

  • remote_host (String)

    remote host

  • remote_port (Integer)

    remote port

  • local_host (String) (defaults to: nil)

    local host

  • local_port (Integer) (defaults to: nil)

    local port


240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/polyphony/extensions/socket.rb', line 240

def initialize(remote_host, remote_port, local_host = nil, local_port = nil)
  remote_addr = Addrinfo.tcp(remote_host, remote_port)
  @io = Socket.new remote_addr.afamily, Socket::SOCK_STREAM
  if local_host && local_port
    addr = Addrinfo.tcp(local_host, local_port)
    @io.bind(addr)
  end

  return unless remote_host && remote_port

  addr = Addrinfo.tcp(remote_host, remote_port)
  @io.connect(addr)
end

Instance Method Details

#<<(msg) ⇒ Object

:nop-doc:


20
21
22
23
# File 'ext/polyphony/socket_extensions.c', line 20

VALUE Socket_double_chevron(VALUE self, VALUE msg) {
  Backend_send(BACKEND(), self, msg, INT2FIX(0));
  return self;
}

#closeTCPSocket

Closes the socket.

Returns:


260
261
262
263
# File 'lib/polyphony/extensions/socket.rb', line 260

def close
  @io ? @io.close : orig_close
  self
end

#closed?bool

Returns true if the socket is closed.

Returns:

  • (bool)

    is socket closed


282
283
284
# File 'lib/polyphony/extensions/socket.rb', line 282

def closed?
  @io ? @io.closed? : orig_closed?
end

#dont_linger::Socket

Sets the linger option to 0.

Returns:


289
290
291
292
# File 'lib/polyphony/extensions/socket.rb', line 289

def dont_linger
  setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, Socket::ZERO_LINGER)
  self
end

#feed_loop(receiver, method = :call, &block) ⇒ Socket

Receives data from the socket in an infinite loop, passing the data to the given receiver using the given method. If a block is given, the result of the method call to the receiver is passed to the block.

This method can be used to feed data into parser objects. The following example shows how to feed data from a socket directly into a MessagePack unpacker:

unpacker = MessagePack::Unpacker.new conn.feed_loop(unpacker, :feed_each) { |msg| handle_msg(msg) }

Parameters:

  • receiver (any)

    receiver object

  • method (Symbol) (defaults to: :call)

    method to call

Returns:


389
390
391
# File 'lib/polyphony/extensions/socket.rb', line 389

def feed_loop(receiver, method = :call, &block)
  Polyphony.backend_recv_feed_loop(self, receiver, method, &block)
end

#no_delay::Socket

Sets the NODELAY option.

Returns:


297
298
299
300
# File 'lib/polyphony/extensions/socket.rb', line 297

def no_delay
  setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
  self
end

#read(len = nil, buf = nil, buffer_pos = 0) ⇒ String

Reads from the socket. If maxlen is given, reads up to maxlen bytes from the socket, otherwise reads to EOF. If buf is given, it is used as the buffer to read into, otherwise a new string is allocated. If buffer_pos is given, reads into the given offset (in bytes) in the given buffer. If the given buffer offset is negative, it is calculated from the current end of the buffer (-1 means the read data will be appended to the end of the buffer).

If no bytes are available and EOF is not hit, this method will block until the socket is ready to read from.

Parameters:

  • len (Integer, nil) (defaults to: nil)

    maximum bytes to read from socket

  • buf (String, nil) (defaults to: nil)

    buffer to read into

  • buffer_pos (Number) (defaults to: 0)

    buffer position to read into

Returns:

  • (String)

    buffer used for reading


336
337
338
339
340
341
342
343
344
345
346
347
# File 'lib/polyphony/extensions/socket.rb', line 336

def read(len = nil, buf = nil, buffer_pos = 0)
  return '' if len == 0
  return Polyphony.backend_read(self, buf, len, true, buffer_pos) if buf

  @read_buffer ||= +''
  result = Polyphony.backend_read(self, @read_buffer, len, true, -1)
  return nil unless result

  already_read = @read_buffer
  @read_buffer = +''
  already_read
end

#read_nonblock(maxlen, buf = nil, exception: true) ⇒ String, :wait_readable

Performs a non-blocking read from the socket of up to maxlen bytes. If buf is given, it is used as the read buffer, otherwise a new string will be allocated. If the socket is not ready for reading and exception is true, an IO::WaitReadable will be raised. If the socket is not ready for reading and exception is false, :wait_readable is returned.

Parameters:

  • maxlen (Integer)

    maximum bytes to read

  • buf (String, nil) (defaults to: nil)

    read buffer

  • exception (bool) (defaults to: true)

    whether to raise an exception if not ready for reading

Returns:

  • (String, :wait_readable)

    read buffer


426
427
428
# File 'lib/polyphony/extensions/socket.rb', line 426

def read_nonblock(maxlen, buf = nil, exception: true)
  @io.read_nonblock(maxlen, buf, exception:)
end

#readpartial(maxlen, buf = +'',, buffer_pos = 0, raise_on_eof = true) ⇒ String?

Reads up to maxlen from the socket. If buf is given, it is used as the buffer to read into, otherwise a new string is allocated. If buffer_pos is given, reads into the given offset (in bytes) in the given buffer. If the given buffer offset is negative, it is calculated from the current end of the buffer (-1 means the read data will be appended to the end of the buffer). If raise_on_eof is true (the default,) an EOFError will be raised on EOF, otherwise nil will be returned.

If no bytes are available and EOF is not hit, this method will block until the socket is ready to read from.

Parameters:

  • maxlen (Integer, nil)

    maximum bytes to read from socket

  • buf (String, nil) (defaults to: +'',)

    buffer to read into

  • buffer_pos (Number) (defaults to: 0)

    buffer position to read into

  • raise_on_eof (bool) (defaults to: true)

    whether to raise an exception on EOF

Returns:

  • (String, nil)

    buffer used for reading or nil on EOF

Raises:

  • (EOFError)

409
410
411
412
413
414
# File 'lib/polyphony/extensions/socket.rb', line 409

def readpartial(maxlen, buf = +'', buffer_pos = 0, raise_on_eof = true)
  result = Polyphony.backend_recv(self, buf, maxlen, buffer_pos)
  raise EOFError if !result && raise_on_eof

  result
end

#recv(maxlen, flags = 0, outbuf = nil) ⇒ String

Receives up to maxlen bytes from the socket. If outbuf is given, it is used as the buffer to receive into, otherwise a new string is allocated and used as buffer.

If no bytes are available, this method will block until the socket is ready to receive from.

Parameters:

  • maxlen (Integer)

    maximum bytes to receive

  • flags (Integer) (defaults to: 0)

    receive flags

  • outbuf (String, nil) (defaults to: nil)

    buffer for reading or nil to allocate new string

Returns:

  • (String)

    receive buffer


360
361
362
# File 'lib/polyphony/extensions/socket.rb', line 360

def recv(maxlen, flags = 0, outbuf = nil)
  Polyphony.backend_recv(self, outbuf || +'', maxlen, 0)
end

#recv_loop(maxlen = 8192) {|String| ... } ⇒ Socket Also known as: read_loop

Receives up to maxlen bytes at a time in an infinite loop. Read buffers will be passed to the given block.

Parameters:

  • maxlen (Integer) (defaults to: 8192)

    maximum bytes to receive

Yields:

  • (String)

    received data

Returns:


370
371
372
# File 'lib/polyphony/extensions/socket.rb', line 370

def recv_loop(maxlen = 8192, &block)
  Polyphony.backend_recv_loop(self, maxlen, &block)
end

#reuse_addr::Socket

Sets the REUSEADDR option.

Returns:


305
306
307
308
# File 'lib/polyphony/extensions/socket.rb', line 305

def reuse_addr
  setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
  self
end

#reuse_port::Socket

Sets the REUSEPORT option.

Returns:


313
314
315
316
# File 'lib/polyphony/extensions/socket.rb', line 313

def reuse_port
  setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_REUSEPORT, 1)
  self
end

#send(msg, flags) ⇒ Object

:nop-doc:


5
6
7
# File 'ext/polyphony/socket_extensions.c', line 5

VALUE Socket_send(VALUE self, VALUE msg, VALUE flags) {
  return Backend_send(BACKEND(), self, msg, flags);
}

#setsockopt(*args) ⇒ TCPSocket

Calls setsockopt with the given arguments.

Returns:


271
272
273
274
# File 'lib/polyphony/extensions/socket.rb', line 271

def setsockopt(*args)
  @io ? @io.setsockopt(*args) : orig_setsockopt(*args)
  self
end

#write(*args) ⇒ Object

:nop-doc:


11
12
13
14
15
16
# File 'ext/polyphony/socket_extensions.c', line 11

VALUE Socket_write(int argc, VALUE *argv, VALUE self) {
  VALUE ary = rb_ary_new_from_values(argc, argv);
  VALUE result = Backend_sendv(BACKEND(), self, ary, INT2FIX(0));
  RB_GC_GUARD(ary);
  return result;
}

#write_nonblock(buf, exception: true) ⇒ Integer, :wait_readable

Performs a non-blocking to the socket. If the socket is not ready for writing and exception is true, an IO::WaitWritable will be raised. If the socket is not ready for writing and exception is false, :wait_writable is returned.

Parameters:

  • buf (String, nil)

    write buffer

  • exception (bool) (defaults to: true)

    whether to raise an exception if not ready for reading

Returns:

  • (Integer, :wait_readable)

    number of bytes written


438
439
440
# File 'lib/polyphony/extensions/socket.rb', line 438

def write_nonblock(buf, exception: true)
  @io.write_nonblock(buf, exception:)
end