:sourcedir: {core}/src/main/java
:examples-link: {reactor-netty-github-repo}/reactor-netty-examples/src/main/java/reactor/netty/examples/documentation/udp/client
:examples-dir: {examples}/src/main/java/reactor/netty/examples/documentation/udp/client
:wirelogger: reactor.netty.udp.UdpClient

[[udp-client]]
= UDP Client

Reactor Netty provides the easy-to-use and easy-to-configure
{javadoc}/reactor/netty/udp/UdpClient.html[`UdpClient`].
It hides most of the Netty functionality that is required to create a `UDP` client
and adds Reactive Streams backpressure.

[[connecting-and-disconnecting]]
== Connecting and Disconnecting

To connect the UDP client to a given endpoint, you must create and configure a
{javadoc}/reactor/netty/udp/UdpClient.html[UdpClient] instance.
By default, the host is configured for `localhost` and the port is `12012`.
The following example shows how to create and connect a UDP client:

{examples-link}/create/Application.java
[%unbreakable]
----
include::{examples-dir}/create/Application.java[lines=18..32]
----
<1> Creates a {javadoc}/reactor/netty/udp/UdpClient.html[`UdpClient`]
instance that is ready for configuring.
<2> Connects the client in a blocking fashion and waits for it to finish initializing.

The returned {javadoc}/reactor/netty/Connection.html[`Connection`]
offers a simple connection API, including {javadoc}/reactor/netty/DisposableChannel.html#disposeNow-java.time.Duration-[`disposeNow()`],
which shuts the client down in a blocking fashion.

[[host-and-port]]
=== Host and Port

To connect to a specific `host` and `port`, you can apply the following configuration to the `UDP` client:

{examples-link}/address/Application.java
[%unbreakable]
----
include::{examples-dir}/address/Application.java[lines=18..34]
----
<1> Configures the `host` to which this client should connect
<2> Configures the `port` to which this client should connect

NOTE: The port can be specified also with *PORT* environment variable.

[[eager-initialization]]
== Eager Initialization

By default, the initialization of the `UdpClient` 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)

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

{examples-link}/warmup/Application.java
[%unbreakable]
----
include::{examples-dir}/warmup/Application.java[lines=18..40]
----
<1> Initialize and load the event loop group, the host name resolver, and the native transport libraries
<2> Host name resolution happens when connecting to the remote peer

[[writing-data]]
== Writing Data

To send data to a given peer, you must attach an I/O handler.
The I/O handler has access to {javadoc}/reactor/netty/udp/UdpOutbound.html[`UdpOutbound`],
to be able to write data.

The following example shows how to send `hello`:

{examples-link}/send/Application.java
[%unbreakable]
----
include::{examples-dir}/send/Application.java[lines=18..37]
----
<1> Sends `hello` string to the remote peer.

[[consuming-data]]
== Consuming Data

To receive data from a given peer, you must attach an I/O handler.
The I/O handler has access to {javadoc}/reactor/netty/udp/UdpInbound.html[`UdpInbound`],
to be able to read data.
The following example shows how to consume data:

{examples-link}/read/Application.java
[%unbreakable]
----
include::{examples-dir}/read/Application.java[lines=18..35]
----
<1> Receives data from a given peer

[[lifecycle-callbacks]]
== Lifecycle Callbacks

The following lifecycle callbacks are provided to let you extend the `UdpClient`:

[width="100%",options="header"]
|=======
| 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:

{examples-link}/lifecycle/Application.java
[%unbreakable]
----
include::{examples-dir}/lifecycle/Application.java[lines=18..40]
----
<1> `Netty` pipeline is extended with `LineBasedFrameDecoder` when the channel has been connected.
<2> `Netty` pipeline is extended with `LoggingHandler` when initializing the channel.

[[connection-configuration]]
== Connection Configuration

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

* xref:udp-client.adoc#client-udp-connection-configurations-channel-options[Channel Options]
* xref:udp-client.adoc#client-udp-connection-configurations-wire-logger[Wire Logger]
* xref:udp-client.adoc#client-udp-connection-configurations-event-loop-group[Event Loop Group]

[[client-udp-connection-configurations-channel-options]]
=== Channel Options

By default, the `UDP` client is configured with the following options:

{core-source-link}/reactor/netty/udp/UdpClientConnect.java
[%unbreakable]
----
include::{sourcedir}/reactor/netty/udp/UdpClientConnect.java[lines=37..42]
----

If you need additional options or need to change the current options, you can apply the following configuration:

{examples-link}/channeloptions/Application.java
[%unbreakable]
----
include::{examples-dir}/channeloptions/Application.java[lines=18..36]
----

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

* {nettyjavadoc}/io/netty/channel/ChannelOption.html[Common ChannelOption]
* {nettyjavadoc}/io/netty/channel/epoll/EpollChannelOption.html[Epoll ChannelOption]
* {nettyjavadoc}/io/netty/channel/kqueue/KQueueChannelOption.html[KQueue ChannelOption]
* https://docs.oracle.com/javase/8/docs/technotes/guides/net/socketOpt.html[Socket Options]

[[client-udp-connection-configurations-wire-logger]]
include::partial$wire-logger.adoc[]

[[client-udp-connection-configurations-event-loop-group]]
include::partial$eventloop.adoc[]

[[metrics]]
== Metrics
The UDP client supports built-in integration with https://micrometer.io/[`Micrometer`].
It exposes all metrics with a prefix of `reactor.netty.udp.client`.

The following table provides information for the UDP client metrics:

[width="100%",options="header"]
|=======
| metric name | type | description
| reactor.netty.udp.client.data.received | DistributionSummary | Amount of the data received, in bytes.
See xref:observability.adoc#observability-metrics-data-received[Data Received]
| reactor.netty.udp.client.data.sent | DistributionSummary | Amount of the data sent, in bytes.
See xref:observability.adoc#observability-metrics-data-sent[Data Sent]
| reactor.netty.udp.client.errors | Counter | Number of errors that occurred.
See xref:observability.adoc#observability-metrics-errors-count[Errors Count]
| reactor.netty.udp.client.connect.time | Timer | Time spent for connecting to the remote address.
See xref:observability.adoc#observability-metrics-connect-time[Connect Time]
| reactor.netty.udp.client.address.resolver | Timer | Time spent for resolving the address.
See xref:observability.adoc#observability-metrics-hostname-resolution-time[Hostname Resolution Time]
|=======

These additional metrics are also available:

include::partial$alloc-metrics.adoc[]
include::partial$eventloop-metrics.adoc[]

The following example enables that integration:

{examples-link}/metrics/Application.java
[%unbreakable]
----
include::{examples-dir}/metrics/Application.java[lines=18..36]
----
<1> Enables the built-in integration with Micrometer

When UDP 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:

{examples-link}/metrics/custom/Application.java
[%unbreakable]
----
include::{examples-dir}/metrics/custom/Application.java[lines=18..37]
----
<1> Enables UDP client metrics and provides {javadoc}/reactor/netty/channel/ChannelMetricsRecorder.html[`ChannelMetricsRecorder`] implementation.

[[unix-domain-sockets]]
== Unix Domain Sockets
The `UdpClient` supports Unix Domain Datagram Sockets (UDS) when native transport is in use.

The following example shows how to use UDS support:

{examples-link}/uds/Application.java
[%unbreakable]
----
include::{examples-dir}/uds/Application.java[lines=18..42]
----
<1> Specifies `DomainSocketAddress` that will be used
