Class AbstractNettyIOClient<T,U extends SocketAddress>
- All Implemented Interfaces:
IOClient<T>
,NettyIOClient<T>
- Direct Known Subclasses:
SerialIOClient
,TCPIOClient
,UDPIOClient
,WebsocketIOClient
IOClient
implementation for netty.
It uses the netty component for managing the connection.
Concrete implementations are responsible for providing the ChannelOutboundHandler
s and
ChannelInboundHandler
s required to encode/decode the specific type of messages sent/received to/from this
client. For IOClient
s that require some specific encoders/decoders irrespective of the message type (e.g.
UDPIOClient
and WebsocketIOClient
)
the addEncodersDecoders(io.netty.channel.Channel)
method can be overridden so the IOClient
can exactly control
the order and types of encoders/decoders in the pipeline.
Users of the IOClient
can add encoders/decoders for their specific message type using the
setEncoderDecoderProvider(java.util.function.Supplier<io.netty.channel.ChannelHandler[]>)
, each IOClient
should make it clear to users what the required output
type(s) are for the last encoder and decoder that a user may wish to add, if adding encoders/decoders is not
supported then IOClient
s should override this setter and throw an UnsupportedOperationException
.
Typically for outgoing messages a single ChannelOutboundHandler
is sufficient and the
AbstractNettyIOClient.MessageToByteEncoder
can be used as a base.
For inbound messages; the decoders required are very much dependent on the message type and IOClient
type,
any number of standard netty ChannelInboundHandler
s can be used but the last handler should build messages
of type <T> and pass them to the onMessageReceived(T)
method of the client; the AbstractNettyIOClient.ByteToMessageDecoder
or AbstractNettyIOClient.MessageToByteEncoder
can be used for this purpose, which one to use will depend on the previous
ChannelInboundHandler
s in the pipeline.
NOTE: Care must be taken when working with Netty ByteBuf
as Netty uses reference counting to manage their
lifecycle. Refer to the Netty documentation for more information.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic class
This is intended to be used at the end of a decoder chain where the previous decoder outputs aByteBuf
; the providedAbstractNettyIOClient.ByteToMessageDecoder.decoder
should extract the messages of type <T> from theByteBuf
and add them to theList
and they will then be passed to theIOClient
.static class
Concrete implementations must provide an encoder to fill theByteBuf
ready to be sent `over the wire`.static class
This is intended to be used at the end of a decoder chain where the previous decoder outputs messages of type <T>. -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected io.netty.bootstrap.Bootstrap
protected io.netty.channel.Channel
protected org.openremote.model.asset.agent.ConnectionStatus
protected CompletableFuture<Void>
protected int
protected Supplier<io.netty.channel.ChannelHandler[]>
protected ExecutorService
static long
static long
protected ScheduledExecutorService
protected io.netty.channel.EventLoopGroup
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoid
addConnectionStatusConsumer
(Consumer<org.openremote.model.asset.agent.ConnectionStatus> connectionStatusConsumer) Add a consumer of connection statusprotected void
addEncodersDecoders
(io.netty.channel.Channel channel) void
addMessageConsumer
(Consumer<T> messageConsumer) Add a consumer of received messagesprotected void
void
connect()
Connect to the devicevoid
Disconnect from the deviceprotected void
protected void
protected abstract Class<? extends io.netty.channel.Channel>
org.openremote.model.asset.agent.ConnectionStatus
Get current connection statusint
protected abstract io.netty.channel.EventLoopGroup
protected void
initChannel
(io.netty.channel.Channel channel) Inserts the decoders and encoders into the channel pipeline and configures standard exception handling and loggingprotected void
onConnectionStatusChanged
(org.openremote.model.asset.agent.ConnectionStatus connectionStatus) protected void
onDecodeException
(io.netty.channel.ChannelHandlerContext ctx, io.netty.handler.codec.DecoderException decoderException) protected void
onEncodeException
(io.netty.channel.ChannelHandlerContext ctx, io.netty.handler.codec.EncoderException encoderException) protected void
onMessageReceived
(T message) void
Remove every consumer of connection statusvoid
Remove every consumer of received messagesvoid
removeConnectionStatusConsumer
(Consumer<org.openremote.model.asset.agent.ConnectionStatus> connectionStatusConsumer) Remove a consumer of connection statusvoid
removeMessageConsumer
(Consumer<T> messageConsumer) Remove a consumer of received messagesprotected void
scheduleDoConnect
(long initialDelay) void
sendMessage
(T message) Send a message over the wirevoid
setConnectTimeoutMillis
(int connectTimeout) void
setEncoderDecoderProvider
(Supplier<io.netty.channel.ChannelHandler[]> encoderDecoderProvider) Allows appropriate encoders and decoders to be added to the message pipeline; if anIOClient
doesn't support this then anUnsupportedOperationException
will be thrown, consult theIOClient
's documentation.Start the actual connection and return a future indicating completion state.static CompletableFuture<Void>
toCompletableFuture
(Future<Void> future) toString()
protected Void
waitForConnectFuture
(Future<Void> connectFuture) Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
Methods inherited from interface org.openremote.agent.protocol.io.IOClient
getClientUri
-
Field Details
-
RECONNECT_DELAY_INITIAL_MILLIS
public static long RECONNECT_DELAY_INITIAL_MILLIS -
RECONNECT_DELAY_MAX_MILLIS
public static long RECONNECT_DELAY_MAX_MILLIS -
messageConsumers
-
connectionStatusConsumers
-
connectionStatus
protected org.openremote.model.asset.agent.ConnectionStatus connectionStatus -
channel
protected io.netty.channel.Channel channel -
bootstrap
protected io.netty.bootstrap.Bootstrap bootstrap -
workerGroup
protected io.netty.channel.EventLoopGroup workerGroup -
executorService
-
scheduledExecutorService
-
connectRetry
-
connectTimeout
protected int connectTimeout -
encoderDecoderProvider
-
-
Constructor Details
-
AbstractNettyIOClient
protected AbstractNettyIOClient()
-
-
Method Details
-
setEncoderDecoderProvider
public void setEncoderDecoderProvider(Supplier<io.netty.channel.ChannelHandler[]> encoderDecoderProvider) throws UnsupportedOperationException Description copied from interface:NettyIOClient
Allows appropriate encoders and decoders to be added to the message pipeline; if anIOClient
doesn't support this then anUnsupportedOperationException
will be thrown, consult theIOClient
's documentation.- Specified by:
setEncoderDecoderProvider
in interfaceNettyIOClient<T>
- Throws:
UnsupportedOperationException
-
getConnectTimeoutMillis
public int getConnectTimeoutMillis() -
setConnectTimeoutMillis
public void setConnectTimeoutMillis(int connectTimeout) -
getChannelClass
-
getWorkerGroup
protected abstract io.netty.channel.EventLoopGroup getWorkerGroup() -
startChannel
Start the actual connection and return a future indicating completion state. Implementors can also add any custom connection logic they require. -
configureChannel
protected void configureChannel() -
connect
public void connect()Description copied from interface:IOClient
Connect to the device -
scheduleDoConnect
protected void scheduleDoConnect(long initialDelay) -
waitForConnectFuture
- Throws:
Exception
-
doConnect
-
disconnect
public void disconnect()Description copied from interface:IOClient
Disconnect from the device- Specified by:
disconnect
in interfaceIOClient<T>
-
doReconnect
protected void doReconnect() -
doDisconnect
protected void doDisconnect() -
sendMessage
Description copied from interface:IOClient
Send a message over the wire- Specified by:
sendMessage
in interfaceIOClient<T>
-
getConnectionStatus
public org.openremote.model.asset.agent.ConnectionStatus getConnectionStatus()Description copied from interface:IOClient
Get current connection status- Specified by:
getConnectionStatus
in interfaceIOClient<T>
-
addConnectionStatusConsumer
public void addConnectionStatusConsumer(Consumer<org.openremote.model.asset.agent.ConnectionStatus> connectionStatusConsumer) Description copied from interface:IOClient
Add a consumer of connection status- Specified by:
addConnectionStatusConsumer
in interfaceIOClient<T>
-
removeConnectionStatusConsumer
public void removeConnectionStatusConsumer(Consumer<org.openremote.model.asset.agent.ConnectionStatus> connectionStatusConsumer) Description copied from interface:IOClient
Remove a consumer of connection status- Specified by:
removeConnectionStatusConsumer
in interfaceIOClient<T>
-
removeAllConnectionStatusConsumers
public void removeAllConnectionStatusConsumers()Description copied from interface:IOClient
Remove every consumer of connection status- Specified by:
removeAllConnectionStatusConsumers
in interfaceIOClient<T>
-
addMessageConsumer
Description copied from interface:IOClient
Add a consumer of received messages- Specified by:
addMessageConsumer
in interfaceIOClient<T>
-
removeMessageConsumer
Description copied from interface:IOClient
Remove a consumer of received messages- Specified by:
removeMessageConsumer
in interfaceIOClient<T>
-
removeAllMessageConsumers
public void removeAllMessageConsumers()Description copied from interface:IOClient
Remove every consumer of received messages- Specified by:
removeAllMessageConsumers
in interfaceIOClient<T>
-
initChannel
Inserts the decoders and encoders into the channel pipeline and configures standard exception handling and logging- Throws:
Exception
-
addEncodersDecoders
- Throws:
Exception
-
onMessageReceived
-
onDecodeException
protected void onDecodeException(io.netty.channel.ChannelHandlerContext ctx, io.netty.handler.codec.DecoderException decoderException) -
onEncodeException
protected void onEncodeException(io.netty.channel.ChannelHandlerContext ctx, io.netty.handler.codec.EncoderException encoderException) -
onConnectionStatusChanged
protected void onConnectionStatusChanged(org.openremote.model.asset.agent.ConnectionStatus connectionStatus) -
toString
-
toCompletableFuture
public static CompletableFuture<Void> toCompletableFuture(Future<Void> future) throws UnsupportedOperationException - Throws:
UnsupportedOperationException
-