Best way to have Netty Client attempt recconnection if remote peer disconnects? - tcp

I've implemented Netty client code that connects to a server. If the server closes the connection viathe disconnect message, we want the client to continually try to reconnect?
Is this best way to handle TCP Disconnect through the channelInactive callback?
Also, channelInactive will not handle TCP timeout, correct?

channelInactive or adding a ChannelFutureListener to Channel.closeFuture() is the right way to handle this. Just be aware you can not "reconnect" and existing Channel but need to bootstrap a new one.

Related

Abort HTTP request without closing the connection in Netty

How can I abort the HTTP Request and not close the connection while implementing a netty HTTP client?
At the moment I am using NioSocketChannel and I am confused if doClose is the only option.
Is there a more generic way of canceling the request, that can work with any kind of socket channel, eg KQueue?
Netty's ChannelFuture extends the netty Future which provides a cancel method: https://netty.io/4.0/api/io/netty/util/concurrent/Future.html#cancel-boolean-
I'm pretty sure that's what you're looking for.
doClose closes the channel where a channel is described as "A nexus to a network socket or a component which is capable of I/O operations such as read, write, connect, and bind." So that would close the connection, as you're seeing. It doesn't look like that's going to help you.

Checking connection between server and client without sending multiple packet every second

as stated above, im trying to checking connection between server and client, without using ping, or some packet that will send every second.
i already try ping method, but this method will cause flooding, and i already try tcp method that act like icmp, the tcp packet will send tcp packet every second, to make sure the connection betweet sever and client still on, but this doesnt solve the flooding problem.
do you guys have any idea how to do this, without causing flooding?
all i need is server only send like 3 way handshake, and the connection built, and when the client off, something will trigger the server, and tell that server that, this client in particular are offline.
in simple, how to monitor client and server connectoin without sending multiple packet?
thank you
Say some link halfway between the client and server stops passing traffic. It may or may not still be possible for the client and server to communicate, depending on whether there are alternate links. But there is no way to tell whether or not that communication is possible without doing something active. There is no passive way to tell whether or not a link failure has made a connection usable or unusable.
There is, in general, no easier or more efficient way to tell whether or not communication is possible than attempting that communication and seeing whether or not it works.

Spring Integration. TCP Server Factory

probably is an easy way to do,
What I want to is:
I have a tcp server which listens to the incoming connection.
I would like to be informed somehow when a client connected.
TcpNetServerConnectionFactory has inside such information "Accepted connection ...".
There is TcpConnectionSupport class, however I cannot find a way how to use it. I am looking something similar to subscriber pattern.
Is there some way to do it?
From one side it isn't clear how you want to implement subscriber pattern, if it is a Spring Integration out-of-the-box feature with <int-ip:tcp-inbound-channel-adapter connection-factory="connectionFactory"/>. When the new connection from client is established and client starts to send the data that component will be ready to receive it and convert to the message to send to the channel for further integration flow.
From other side there is an ApplicationEvent infrastructure, and when connection is open, the TcpNetServerConnectionFactory emits TcpConnectionOpenEvent. You can listen to this event using <int-event:inbound-channel-adapter event-types="org.springframework.integration.ip.tcp.connection.TcpConnectionOpenEvent"/>.
And again: it will be a message flow.

TCP keep-alive to determine if client disconnected in netty

I'm trying to determine if a client has closed a socket connection from netty. Is there a way to do this?
On a usual case where a client closes the socket via close() and the TCP closing handshake has been finished successfully, a channelInactive() (or channelClosed() in 3) event will be triggered.
However, on an unusual case such as where a client machine goes offline due to power outage or unplugged LAN cable, it can take a lot of time until you discover the connection was actually down. To detect this situation, you have to send some message to the client periodically and expect to receive its response within a certain amount of time. It's like a ping - you should define a periodic ping and pong message in your protocol which practically does nothing but checking the health of the connection.
Alternatively, you can enable SO_KEEPALIVE, but the keepalive interval of this option is usually OS-dependent and I would not recommend using it.
To help a user implement this sort of behavior relatively easily, Netty provides ReadTimeoutHandler. Configure your pipeline so that ReadTimeoutHandler raises an exception when there's no inbound traffic for a certain amount of time, and close the connection on the exception in your exceptionCaught() handler method. If you are the party who is supposed to send a periodic ping message, use a timer (or IdleStateHandler) to send it.
If you are writing a server, and netty is your client, then your server can detect a disconnect by calling select() or equivalent to detect when the socket is readable and then call recv(). If recv() returns 0 then the socket was closed gracefully by the client. If recv() returns -1 then check errno or equivalent for the actual error (with few exceptions, most errors should be treated as an ungraceful disconnect). The thing about unexpected disconnects is that they can take a long time for the OS to detect, so you would have to either enable TCP keep-alives, or require the client to send data to the server on a regular basis. If nothing is received from the client for a period of time then just assume the client is gone and close your end of the connection. If the client wants to, it can then reconnect.
If you read from a connection that has been closed by the peer you will get an end-of-stream indication of some kind, depending on the API. If you write to such a connection you will get an IOException: 'connection reset'. TCP doesn't provide any other way of detecting a closed connection.
TCP keep-alive (a) is off by default and (b) only operates every two hours by default when enabled. This probably isn't what you want. If you use it and you read or write after it has detected that the connection is broken, you will get the reset error above,
It depends on your protocol that you use ontop of netty. If you design it to support ping-like messages, you can simply send those messages. Besides that, netty is only a pretty thin wrapper around TCP.
Also see this SO post which describes isOpen() and related. This however does not solve the keep-alive problem.

how to determine if the client received the message using SignalR

If I send a messag using SignalR, is it possible that the client does not receive the message? How can you verify if any errors apeared in the communication? Iam thinking of sending a message back to server after the server notification was sent, but is there any better way?
Yes, it's possible that the client doesn't receive the message. SignalR keeps messages in memory for 30 seconds (by default, you can tweak that or use a persistent message bus), so if the client isn't connected for whatever reason and this timeout passes the client will miss the message. Note that if he reconnects within this period he receives all messages he hasn't got yet, including those that were sent when he was disconnected.
I don't know if SignalR provides a way of telling you when a broadcast failed, so it might be safer to just send an acknowledgement back to the server.
As long as the client is connected, it will get the messages. You can subscribe to connection state changes in client side code. In server side code you can implement IConnected and IDisconnect interfaces to handle the Connect, Disconnect, and Reconnect events.

Resources