Class: JRPC::Transport::SocketTcp

Inherits:
SocketBase show all
Defined in:
lib/jrpc/transport/socket_tcp.rb

Instance Attribute Summary

Attributes inherited from SocketBase

#options, #read_timeout, #write_timeout

Instance Method Summary collapse

Methods inherited from SocketBase

connect, #connect, #initialize

Constructor Details

This class inherits a constructor from JRPC::Transport::SocketBase

Instance Method Details

#check_fin_signalObject

Socket implementation allows client to send data to server after FIN, but server will never receive this data. We correctly close socket from client side when FIN event received. Should be checked before send data to socket or recv data from socket.



65
66
67
# File 'lib/jrpc/transport/socket_tcp.rb', line 65

def check_fin_signal
  close if socket && !socket.closed? && fin_signal?
end

#closeObject



41
42
43
44
# File 'lib/jrpc/transport/socket_tcp.rb', line 41

def close
  return if @socket.nil?
  socket.close
end

#closed?Boolean

Socket implementation allows client to send data to server after FIN, but server will never receive this data. So we consider socket closed when it have FIN event and close it correctly from client side.

Returns:

  • (Boolean)


50
51
52
53
54
55
56
57
58
59
# File 'lib/jrpc/transport/socket_tcp.rb', line 50

def closed?
  return true if @socket.nil? || socket.closed?

  if fin_signal?
    close
    return true
  end

  false
end

#read(length, timeout = @read_timeout) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/jrpc/transport/socket_tcp.rb', line 5

def read(length, timeout = @read_timeout)
  received = ''
  length_to_read = length
  while length_to_read > 0
    io_read, = IO.select([socket], [], [], timeout)
    raise ReadTimeoutError unless io_read
    check_fin_signal
    chunk = io_read[0].read_nonblock(length_to_read)
    received += chunk
    length_to_read -= chunk.bytesize
  end
  received
rescue Errno::EPIPE, EOFError => e
  # EPIPE, in this case, means that the data connection was unexpectedly terminated.
  clear_socket!
  raise ReadFailedError, "#{e.class} #{e.message}"
end

#socketObject



69
70
71
# File 'lib/jrpc/transport/socket_tcp.rb', line 69

def socket
  @socket ||= build_socket
end

#write(data, timeout = @write_timeout) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/jrpc/transport/socket_tcp.rb', line 23

def write(data, timeout = @write_timeout)
  length_written = 0
  data_to_write = data
  while data_to_write.bytesize > 0
    _, io_write, = IO.select([], [socket], [], timeout)
    raise WriteTimeoutError unless io_write
    check_fin_signal
    chunk_length = io_write[0].write_nonblock(data_to_write)
    length_written += chunk_length
    data_to_write = data.byteslice(length_written, data.length)
  end
  length_written
rescue Errno::EPIPE => e
  # EPIPE, in this case, means that the data connection was unexpectedly terminated.
  clear_socket!
  raise WriteFailedError, "#{e.class} #{e.message}"
end