Skip to content

Latest commit

 

History

History
409 lines (335 loc) · 16.1 KB

tcp-client.adoc

File metadata and controls

409 lines (335 loc) · 16.1 KB

TCP Client

Reactor Netty provides the easy-to-use and easy-to-configure TcpClient. It hides most of the Netty functionality that is needed in order to create a TCP client and adds Reactive Streams backpressure.

Connect and Disconnect

To connect the TCP client to a given endpoint, you must create and configure a TcpClient instance. By default, the host is localhost and the port is 12012. The following example shows how to create a TcpClient:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/create/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/create/Application.java[role=include]
  1. Creates a TcpClient instance that is ready for configuring.

  2. Connects the client in a blocking fashion and waits for it to finish initializing.

The returned Connection offers a simple connection API, including disposeNow(), which shuts the client down in a blocking fashion.

Host and Port

To connect to a specific host and port, you can apply the following configuration to the TCP client. The following example shows how to do so:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/address/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/address/Application.java[role=include]
  1. Configures the TCP host

  2. Configures the TCP port

Eager Initialization

By default, the initialization of the TcpClient resources happens on demand. This means that the connect operation absorbs the extra time needed to initialize and load:

  • the event loop group

  • the host name resolver

  • the native transport libraries (when native transport is used)

  • the native libraries for the security (in case of OpenSsl)

When you need to preload these resources, you can configure the TcpClient as follows:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/warmup/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/warmup/Application.java[role=include]
  1. Initialize and load the event loop group, the host name resolver, the native transport libraries and the native libraries for the security

  2. Host name resolution happens when connecting to the remote peer

Writing Data

To send data to a given endpoint, you must attach an I/O handler. The I/O handler has access to NettyOutbound to be able to write data.

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/send/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/send/Application.java[role=include]
  1. Sends hello string to the endpoint.

When you need more control over the writing process, as an alternative for I/O handler you may use Connection#outbound. As opposed to I/O handler where the connection is closed when the provided Publisher finishes (in case of finite Publisher), when using Connection#outbound, you have to invoke explicitly Connection#dispose in order to close the connection.

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/send/connection/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/send/connection/Application.java[role=include]
  1. Sends hello 1 string to the endpoint.

  2. Sends hello 2 string to the endpoint.

  3. Closes the connection once the message is sent to the endpoint.

Consuming Data

To receive data from a given endpoint, you must attach an I/O handler. The I/O handler has access to NettyInbound to be able to read data. The following example shows how to do so:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/read/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/read/Application.java[role=include]
  1. Receives data from a given endpoint

When you need more control over the reading process, as an alternative for I/O handler you may use Connection#inbound. As opposed to I/O handler where the connection is closed when the provided Publisher finishes (in case of finite Publisher), when using Connection#inbound, you have to invoke explicitly Connection#dispose in order to close the connection.

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/read/connection/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/read/connection/Application.java[role=include]
  1. Receives data from a given endpoint.

Lifecycle Callbacks

The following lifecycle callbacks are provided to let you extend the TcpClient.

Callback Description

doAfterResolve

Invoked after the remote address has been resolved successfully.

doOnChannelInit

Invoked when initializing the channel.

doOnConnect

Invoked when the channel is about to connect.

doOnConnected

Invoked after the channel has been connected.

doOnDisconnected

Invoked after the channel has been disconnected.

doOnResolve

Invoked when the remote address is about to be resolved.

doOnResolveError

Invoked in case the remote address hasn’t been resolved successfully.

The following example uses the doOnConnected and doOnChannelInit callbacks:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/lifecycle/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/lifecycle/Application.java[role=include]
  1. Netty pipeline is extended with ReadTimeoutHandler when the channel has been connected.

  2. Netty pipeline is extended with LoggingHandler when initializing the channel.

TCP-level Configurations

This section describes three kinds of configuration that you can use at the TCP level:

Channel Options

By default, the TCP client is configured with the following options:

./../../reactor-netty-core/src/main/java/reactor/netty/tcp/TcpClientConnect.java
link:./../../reactor-netty-core/src/main/java/reactor/netty/tcp/TcpClientConnect.java[role=include]

If additional options are necessary or changes to the current options are needed, you can apply the following configuration:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/channeloptions/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/channeloptions/Application.java[role=include]

You can find more about Netty channel options at the following links:

Event Loop Group

By default the TCP client uses an “Event Loop Group”, where the number of the worker threads equals the number of processors available to the runtime on initialization (but with a minimum value of 4). When you need a different configuration, you can use one of the LoopResource#create methods.

The following listing shows the default configuration for the Event Loop Group:

./../../reactor-netty-core/src/main/java/reactor/netty/ReactorNetty.java
link:./../../reactor-netty-core/src/main/java/reactor/netty/ReactorNetty.java[role=include]

If you need changes to the these settings, you can apply the following configuration:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/eventloop/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/eventloop/Application.java[role=include]

SSL and TLS

When you need SSL or TLS, you can apply the following configuration. By default, if OpenSSL is available, the SslProvider.OPENSSL provider is used as a provider. Otherwise, the provider is SslProvider.JDK. You can switch the provider by using SslContextBuilder or by setting -Dio.netty.handler.ssl.noOpenSsl=true.

The following example uses SslContextBuilder:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/security/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/security/Application.java[role=include]

Server Name Indication

By default, the TCP client sends the remote host name as SNI server name. When you need to change this default setting, you can configure the TCP client as follows:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/sni/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/sni/Application.java[role=include]

Metrics

The TCP client supports built-in integration with Micrometer. It exposes all metrics with a prefix of reactor.netty.tcp.client.

The following table provides information for the TCP client metrics:

metric name type description

reactor.netty.tcp.client.data.received

DistributionSummary

Amount of the data received, in bytes. See [observability-metrics-data-received]

reactor.netty.tcp.client.data.sent

DistributionSummary

Amount of the data sent, in bytes. See [observability-metrics-data-sent]

reactor.netty.tcp.client.errors

Counter

Number of errors that occurred. See [observability-metrics-errors-count]

reactor.netty.tcp.client.tls.handshake.time

Timer

Time spent for TLS handshake. See [observability-metrics-tls-handshake-time]

reactor.netty.tcp.client.connect.time

Timer

Time spent for connecting to the remote address. See [observability-metrics-connect-time]

reactor.netty.tcp.client.address.resolver

Timer

Time spent for resolving the address. See [observability-metrics-hostname-resolution-time]

These additional metrics are also available:

The following example enables that integration:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/metrics/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/metrics/Application.java[role=include]
  1. Enables the built-in integration with Micrometer

When TCP client metrics are needed for an integration with a system other than Micrometer or you want to provide your own integration with Micrometer, you can provide your own metrics recorder, as follows:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/metrics/custom/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/metrics/custom/Application.java[role=include]
  1. Enables TCP client metrics and provides ChannelMetricsRecorder implementation.

Unix Domain Sockets

The TCP client supports Unix Domain Sockets (UDS) when native transport is in use.

The following example shows how to use UDS support:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/uds/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/uds/Application.java[role=include]
  1. Specifies DomainSocketAddress that will be used

Host Name Resolution

By default, the TcpClient uses Netty’s domain name lookup mechanism that resolves a domain name asynchronously. This is as an alternative of the JVM’s built-in blocking resolver.

When you need to change the default settings, you can configure the TcpClient as follows:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/resolver/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/resolver/Application.java[role=include]
  1. The timeout of each DNS query performed by this resolver will be 500ms.

The following listing shows the available configurations:

Configuration name Description

cacheMaxTimeToLive

The max time to live of the cached DNS resource records (resolution: seconds). If the time to live of the DNS resource record returned by the DNS server is greater than this max time to live, this resolver ignores the time to live from the DNS server and uses use this max time to live. Default to Integer.MAX_VALUE.

cacheMinTimeToLive

The min time to live of the cached DNS resource records (resolution: seconds). If the time to live of the DNS resource record returned by the DNS server is less than this min time to live, this resolver ignores the time to live from the DNS server and uses this min time to live. Default: 0.

cacheNegativeTimeToLive

The time to live of the cache for the failed DNS queries (resolution: seconds). Default: 0.

completeOncePreferredResolved

When this setting is enabled, the resolver notifies as soon as all queries for the preferred address type are complete. When this setting is disabled, the resolver notifies when all possible address types are complete. This configuration is applicable for DnsNameResolver#resolveAll(String). By default, this setting is enabled.

disableOptionalRecord

Disables the automatic inclusion of an optional record that tries to give a hint to the remote DNS server about how much data the resolver can read per response. By default, this setting is enabled.

disableRecursionDesired

Specifies whether this resolver has to send a DNS query with the recursion desired (RD) flag set. By default, this setting is enabled.

hostsFileEntriesResolver

Sets a custom HostsFileEntriesResolver to be used for hosts file entries. Default: DefaultHostsFileEntriesResolver.

maxPayloadSize

Sets the capacity of the datagram packet buffer (in bytes). Default: 4096.

maxQueriesPerResolve

Sets the maximum allowed number of DNS queries to send when resolving a host name. Default: 16.

ndots

Sets the number of dots that must appear in a name before an initial absolute query is made. Default: -1 (to determine the value from the OS on Unix or use a value of 1 otherwise).

queryTimeout

Sets the timeout of each DNS query performed by this resolver (resolution: milliseconds). Default: 5000.

resolvedAddressTypes

The list of the protocol families of the resolved address.

bindAddressSupplier

The supplier of the local address to bind to.

roundRobinSelection

Enables an AddressResolverGroup of DnsNameResolver that supports random selection of destination addresses if multiple are provided by the nameserver. See RoundRobinDnsAddressResolverGroup. Default: DnsAddressResolverGroup

runOn

Performs the communication with the DNS servers on the given LoopResources. By default, the LoopResources specified on the client level are used.

searchDomains

The list of search domains of the resolver. By default, the effective search domain list is populated by using the system DNS search domains.

trace

A specific logger and log level to be used by this resolver when generating detailed trace information in case of resolution failure.

Sometimes, you may want to switch to the JVM built-in resolver. To do so, you can configure the TcpClient as follows:

./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/resolver/custom/Application.java
link:./../../reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/tcp/client/resolver/custom/Application.java[role=include]
  1. Sets the JVM built-in resolver.