Class: Takagi::TcpClient

Inherits:
ClientBase show all
Defined in:
lib/takagi/tcp_client.rb,
sig/takagi/tcp_client.rbs

Overview

CoAP-over-TCP client for testing Takagi servers with TCP transport.

This client implements CoAP over TCP (RFC 8323) with automatic length framing. Unlike the UDP client, TCP provides reliable delivery so no retransmission manager is needed.

Examples:

Basic usage with auto-close (recommended)

Takagi::TcpClient.open('coap+tcp://localhost:5683') do |client|
  client.get('/temperature')
end

Manual lifecycle management

client = Takagi::TcpClient.new('coap+tcp://localhost:5683')
begin
  client.get('/temperature')
ensure
  client.close
end

Instance Attribute Summary

Attributes inherited from ClientBase

#callbacks, #server_uri, #timeout

Instance Method Summary collapse

Methods inherited from ClientBase

#cleanup_resources, #close, #closed?, #delete, #deliver_response, #get, #get_json, #initialize, #observe, #on, open, #parse_json_response, #post, #post_json, #put, #put_json

Constructor Details

This class inherits a constructor from Takagi::ClientBase

Instance Method Details

#request(method, path, payload = nil, options: {}, type: nil) {|arg0| ... } ⇒ Object

Parameters:

  • method (Object)
  • path (Object)
  • payload (Object, nil) (defaults to: nil)

Yields:

Yield Parameters:

  • arg0

Yield Returns:

  • (Object)

Returns:

  • (Object)


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/takagi/tcp_client.rb', line 29

def request(method, path, payload = nil, options: {}, type: nil, &callback)
  uri = URI.join(server_uri.to_s, path)

  # Build options: user options + Uri-Path segments + Uri-Query
  combined = (options || {}).dup
  path_segments = uri.path.split('/').reject(&:empty?)
  unless path_segments.empty?
    combined[CoAP::Registries::Option::URI_PATH] ||= []
    path_segments.each { |s| combined[CoAP::Registries::Option::URI_PATH] << s }
  end
  if uri.query && !uri.query.empty?
    combined[CoAP::Registries::Option::URI_QUERY] ||= []
    uri.query.split('&').each { |q| combined[CoAP::Registries::Option::URI_QUERY] << q }
  end

  # Map method symbol to code via registry
  code = CoAP::CodeHelpers.to_numeric(method)
  token = SecureRandom.hex(4)

  message = Takagi::Message::Outbound.new(
    code: code,
    payload: payload,
    token: token,
    type: type || CoAP::Registries::MessageType::CON,
    options: combined,
    transport: :tcp
  )

  socket = TCPSocket.new(uri.host, uri.port || 5683)
  framed_data = message.to_bytes(transport: :tcp)
  socket.write(framed_data)

  response_data = Takagi::Network::Framing::Tcp.read_from_socket(socket)
  socket.close

  deliver_response(response_data, &callback) if response_data
rescue StandardError => e
  Takagi.logger.error "TakagiTcpClient Error: #{e.message}"
end