You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Mei <me...@163.com> on 2017/10/24 16:42:44 UTC

How to use the heartbeat properly

What version of SSHD are you using?

1.4.0

What JVM are you using (java -version)?

1.8

What did you do?
1、 I creat a ssh client to connect another ssh server (which by openssh) with params
      HEARTBEAT_INTERAL = 60
      IDLE_TIMEOUT = 300
      NIO_READ_TIMEOUT = 315
 with the following code:
PropertyResolverUtils.updateProperty(sshd, FactoryManager.IDLE_TIMEOUT, IDLE_TIMEOUT);
PropertyResolverUtils.updateProperty(sshd, FactoryManager.IDLE_TIMEOUT, NIO_READ_TIMEOUT);
PropertyResolverUtils.updateProperty(sshd, ClientFactoryManager.IDLE_TIMEOUT, HEARTBEAT_INTERAL);
2、Start the client


What did you see?
    what I want to seen is that the client heartbeat can make the keepalive of the connection of client and server.
But  the connection still times out  about the NIO_READ_TIMEOUT seconds.
 1、 I see the code about client heartbeat:
/**
Sends a heartbeat message
@return The {@link IoWriteFuture}
that can be used to wait for the
message write completion
*/
protected IoWriteFuture sendHeartBeat() {
  ClientSession session = getClientSession();
  String request = session.getStringProperty(ClientFactoryManager.HEARTBEAT_REQUEST, ClientFactoryManager.DEFAULT_KEEP_ALIVE_HEARTBEAT_STRING);
  try {
 Buffer buf = session.createBuffer(SshConstants.SSH_MSG_GLOBAL_REQUEST, request.length() + Byte.SIZE); 
buf.putString(request);
 buf.putBoolean(false); 
return session.writePacket(buf); }
  catch (IOException e) {
    if (log.isDebugEnabled())
    { log.debug("Error (" + e.getClass().getSimpleName() + ") sending keepalive message=" + request + ": " + e.getMessage()); }
   Throwable t = e;
   return new AbstractIoWriteFuture(request, null) {
   { setValue(t); }
   };
  }
}
    But I don't know how does the heartbeat work?it only send keepAlive every interal time,but not to check the reply of the keepAlive timeout.
how does the client know that the server is available.Or does other param need to set to make the client heartbeat work?


2、  I have see the sshserver code.
    There is a field named wantReply, the ssh server only reponse the request which want to reply.Then I check the functon above,
    buf.putBoolean(false) have make the wantReply false,So the server not reponse the heartbeat.
    if I change to " buf.putBoolean(true)", then the sshserver will reponse to client. Is it a bug?


3、 To summarise: 
    if I want to matke the ssh cilent know the sshserver if not availbale, how to set the param properly?
    Is it the principle that the sshclient send heartbeat in a interal without regard for reponse,the sshServer will reponse the heartbeat if the sshserver is available,
the sshClient wil refresh the nio_read_timeout if the sshClient receive the reponse.(The HEARTBEAT_INTERAL and NIO_READ_TIMEOUT work together to make the keepalive work?)
Looking forward to your reply,Thanks!
   






Re: How to use the heartbeat properly

Posted by elijah baley <e_...@outlook.com>.
  1.  Please use the latest released version - 1.6.0

>> it only send keepAlive every interal time,but not to check the reply of the keepAlive timeout.

It cannot check for reply since it is a no-reply request

>> how does the client know that the server is available

it doesn't have to - the very attempt to send the keep-alive packet will fail if the server is down...

>> PropertyResolverUtils.updateProperty(sshd, FactoryManager.IDLE_TIMEOUT, IDLE_TIMEOUT);
PropertyResolverUtils.updateProperty(sshd, FactoryManager.IDLE_TIMEOUT, NIO_READ_TIMEOUT);
PropertyResolverUtils.updateProperty(sshd, ClientFactoryManager.IDLE_TIMEOUT, HEARTBEAT_INTERAL);

Seems like you are configuring the server - which doesn't generate keep-alive - only responds to them. Make sure you are configuring the client

>> But  the connection still times out  about the NIO_READ_TIMEOUT seconds.

Make sure that the values are indeed interpreted as seconds

>>  if I change to " buf.putBoolean(true)", then the sshserver will reponse to client. Is it a bug?

it is a bug - the server cannot reply to itt.

>>  if I want to matke the ssh cilent know the sshserver if not availbale, how to set the param properly?

There is no way to "make the client know the server is available" - you can register a SessionListener and be notified that when a session is established or torn down. But if you are creating a session and sending no data on it - there are no guarantees that the session will not be closed by the peer server. If the server is not the Apache SSHD then all bets are off - the server may chose to close an idle session regardless of the heartbeat. I believe it is bad practice to rely on the heartbeat to keep an idle connection open. Better to create session-on-demand or session pool - but this is beyond the scope of this code. Bottom line: don't open SSH connection if you have nothing to do with it...

________________________________
From: Mei <me...@163.com>
Sent: Tuesday, October 24, 2017 7:42 PM
To: dev@mina.apache.org
Subject: How to use the heartbeat properly

What version of SSHD are you using?

1.4.0

What JVM are you using (java -version)?

1.8

What did you do?
1、 I creat a ssh client to connect another ssh server (which by openssh) with params
      HEARTBEAT_INTERAL = 60
      IDLE_TIMEOUT = 300
      NIO_READ_TIMEOUT = 315
 with the following code:
PropertyResolverUtils.updateProperty(sshd, FactoryManager.IDLE_TIMEOUT, IDLE_TIMEOUT);
PropertyResolverUtils.updateProperty(sshd, FactoryManager.IDLE_TIMEOUT, NIO_READ_TIMEOUT);
PropertyResolverUtils.updateProperty(sshd, ClientFactoryManager.IDLE_TIMEOUT, HEARTBEAT_INTERAL);
2、Start the client


What did you see?
    what I want to seen is that the client heartbeat can make the keepalive of the connection of client and server.
But  the connection still times out  about the NIO_READ_TIMEOUT seconds.
 1、 I see the code about client heartbeat:
/**
Sends a heartbeat message
@return The {@link IoWriteFuture}
that can be used to wait for the
message write completion
*/
protected IoWriteFuture sendHeartBeat() {
  ClientSession session = getClientSession();
  String request = session.getStringProperty(ClientFactoryManager.HEARTBEAT_REQUEST, ClientFactoryManager.DEFAULT_KEEP_ALIVE_HEARTBEAT_STRING);
  try {
 Buffer buf = session.createBuffer(SshConstants.SSH_MSG_GLOBAL_REQUEST, request.length() + Byte.SIZE);
buf.putString(request);
 buf.putBoolean(false);
return session.writePacket(buf); }
  catch (IOException e) {
    if (log.isDebugEnabled())
    { log.debug("Error (" + e.getClass().getSimpleName() + ") sending keepalive message=" + request + ": " + e.getMessage()); }
   Throwable t = e;
   return new AbstractIoWriteFuture(request, null) {
   { setValue(t); }
   };
  }
}
    But I don't know how does the heartbeat work?it only send keepAlive every interal time,but not to check the reply of the keepAlive timeout.
how does the client know that the server is available.Or does other param need to set to make the client heartbeat work?

I
2、  I have see the sshserver code.
    There is a field named wantReply, the ssh server only reponse the request which want to reply.Then I check the functon above,
    buf.putBoolean(false) have make the wantReply false,So the server not reponse the heartbeat.
    if I change to " buf.putBoolean(true)", then the sshserver will reponse to client. Is it a bug?


3、 To summarise:
    if I want to matke the ssh cilent know the sshserver if not availbale, how to set the param properly?
    Is it the principle that the sshclient send heartbeat in a interal without regard for reponse,the sshServer will reponse the heartbeat if the sshserver is available,
the sshClient wil refresh the nio_read_timeout if the sshClient receive the reponse.(The HEARTBEAT_INTERAL and NIO_READ_TIMEOUT work together to make the keepalive work?)
Looking forward to your reply,Thanks!