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 ChannelOutboundHandlers and
ChannelInboundHandlers required to encode/decode the specific type of messages sent/received to/from this
client. For IOClients 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 IOClients 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 ChannelInboundHandlers 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
ChannelInboundHandlers 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 classThis is intended to be used at the end of a decoder chain where the previous decoder outputs aByteBuf; the providedAbstractNettyIOClient.ByteToMessageDecoder.decodershould extract the messages of type <T> from theByteBufand add them to theListand they will then be passed to theIOClient.static classConcrete implementations must provide an encoder to fill theByteBufready to be sent `over the wire`.static classThis 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.Bootstrapprotected io.netty.channel.Channelprotected io.netty.channel.ChannelFutureprotected org.openremote.model.asset.agent.ConnectionStatusprotected CompletableFuture<Void>protected Supplier<io.netty.channel.ChannelHandler[]>protected ScheduledExecutorServiceprotected booleanstatic longstatic longprotected io.netty.channel.EventLoopGroup -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidaddConnectionStatusConsumer(Consumer<org.openremote.model.asset.agent.ConnectionStatus> connectionStatusConsumer) Add a consumer of connection statusprotected voidaddEncodersDecoders(io.netty.channel.Channel channel) voidaddMessageConsumer(Consumer<T> messageConsumer) Add a consumer of received messagesprotected voidvoidconnect()Connect to the deviceprotected CompletableFuture<Boolean>voidDisconnect from the deviceprotected voidprotected abstract Class<? extends io.netty.channel.Channel>org.openremote.model.asset.agent.ConnectionStatusGet current connection statusprotected abstract io.netty.channel.EventLoopGroupprotected voidinitChannel(io.netty.channel.Channel channel) Inserts the decoders and encoders into the channel pipelineprotected voidonConnectedFutureComplete(io.netty.util.concurrent.Future<? super Void> future, CompletableFuture<Boolean> connectedFuture) protected voidonConnectionStatusChanged(org.openremote.model.asset.agent.ConnectionStatus connectionStatus) protected voidonDecodeException(io.netty.channel.ChannelHandlerContext ctx, Throwable cause) protected voidonEncodeException(io.netty.channel.ChannelHandlerContext ctx, Throwable cause) protected voidonMessageReceived(T message) voidRemove every consumer of connection statusvoidRemove every consumer of received messagesvoidremoveConnectionStatusConsumer(Consumer<org.openremote.model.asset.agent.ConnectionStatus> connectionStatusConsumer) Remove a consumer of connection statusvoidremoveMessageConsumer(Consumer<T> messageConsumer) Remove a consumer of received messagesprotected voidscheduleDoConnect(boolean immediate) voidsendMessage(T message) Send a message over the wirevoidsetEncoderDecoderProvider(Supplier<io.netty.channel.ChannelHandler[]> encoderDecoderProvider) Allows appropriate encoders and decoders to be added to the message pipeline; if anIOClientdoesn't support this then anUnsupportedOperationExceptionwill be thrown, consult theIOClient's documentation.protected voidsetPermanentError(String message) protected abstract io.netty.channel.ChannelFuturetoString()Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods 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 -
channelStartFuture
protected io.netty.channel.ChannelFuture channelStartFuture -
channel
protected io.netty.channel.Channel channel -
bootstrap
protected io.netty.bootstrap.Bootstrap bootstrap -
workerGroup
protected io.netty.channel.EventLoopGroup workerGroup -
executorService
-
connectRetry
-
permanentError
protected boolean permanentError -
encoderDecoderProvider
-
-
Constructor Details
-
AbstractNettyIOClient
protected AbstractNettyIOClient()
-
-
Method Details
-
setEncoderDecoderProvider
public void setEncoderDecoderProvider(Supplier<io.netty.channel.ChannelHandler[]> encoderDecoderProvider) throws UnsupportedOperationException Description copied from interface:NettyIOClientAllows appropriate encoders and decoders to be added to the message pipeline; if anIOClientdoesn't support this then anUnsupportedOperationExceptionwill be thrown, consult theIOClient's documentation.- Specified by:
setEncoderDecoderProviderin interfaceNettyIOClient<T>- Throws:
UnsupportedOperationException
-
getChannelClass
-
getWorkerGroup
protected abstract io.netty.channel.EventLoopGroup getWorkerGroup() -
startChannel
protected abstract io.netty.channel.ChannelFuture startChannel() -
configureChannel
protected void configureChannel() -
connect
public void connect()Description copied from interface:IOClientConnect to the device -
scheduleDoConnect
protected void scheduleDoConnect(boolean immediate) -
doConnect
-
createConnectedFuture
-
onConnectedFutureComplete
protected void onConnectedFutureComplete(io.netty.util.concurrent.Future<? super Void> future, CompletableFuture<Boolean> connectedFuture) -
disconnect
public void disconnect()Description copied from interface:IOClientDisconnect from the device- Specified by:
disconnectin interfaceIOClient<T>
-
doDisconnect
protected void doDisconnect() -
sendMessage
Description copied from interface:IOClientSend a message over the wire- Specified by:
sendMessagein interfaceIOClient<T>
-
getConnectionStatus
public org.openremote.model.asset.agent.ConnectionStatus getConnectionStatus()Description copied from interface:IOClientGet current connection status- Specified by:
getConnectionStatusin interfaceIOClient<T>
-
addConnectionStatusConsumer
public void addConnectionStatusConsumer(Consumer<org.openremote.model.asset.agent.ConnectionStatus> connectionStatusConsumer) Description copied from interface:IOClientAdd a consumer of connection status- Specified by:
addConnectionStatusConsumerin interfaceIOClient<T>
-
removeConnectionStatusConsumer
public void removeConnectionStatusConsumer(Consumer<org.openremote.model.asset.agent.ConnectionStatus> connectionStatusConsumer) Description copied from interface:IOClientRemove a consumer of connection status- Specified by:
removeConnectionStatusConsumerin interfaceIOClient<T>
-
removeAllConnectionStatusConsumers
public void removeAllConnectionStatusConsumers()Description copied from interface:IOClientRemove every consumer of connection status- Specified by:
removeAllConnectionStatusConsumersin interfaceIOClient<T>
-
addMessageConsumer
Description copied from interface:IOClientAdd a consumer of received messages- Specified by:
addMessageConsumerin interfaceIOClient<T>
-
removeMessageConsumer
Description copied from interface:IOClientRemove a consumer of received messages- Specified by:
removeMessageConsumerin interfaceIOClient<T>
-
removeAllMessageConsumers
public void removeAllMessageConsumers()Description copied from interface:IOClientRemove every consumer of received messages- Specified by:
removeAllMessageConsumersin interfaceIOClient<T>
-
initChannel
protected void initChannel(io.netty.channel.Channel channel) Inserts the decoders and encoders into the channel pipeline -
addEncodersDecoders
protected void addEncodersDecoders(io.netty.channel.Channel channel) -
onMessageReceived
-
onDecodeException
-
onEncodeException
-
onConnectionStatusChanged
protected void onConnectionStatusChanged(org.openremote.model.asset.agent.ConnectionStatus connectionStatus) -
setPermanentError
-
toString
-