2017-09-12 8 views
0

Je fais Netty Server qui satisfait aux conditions suivantes:Comment le serveur Netty sait-il que le client est déconnecté?

  1. Server doit faire le processus de transaction A, lorsqu'il reçoit paquet de son client.
  2. Après la transaction de fin, s'il est encore connecté, il renvoie le message de retour au client. Si non, faites un peu de processus de restauration B.

Mais mon problème est que quand je renvoie au client, le serveur ne sait pas s'il est toujours connecté ou non.

J'ai essayé les codes suivants pour comprendre sa connexion avant d'envoyer des messages. Cependant, il réussit toujours même si le client a déjà fermé sa socket. Il échoue seulement lorsque le processus client est tué de force (par exemple Ctrl + C)

final ChannelFuture cf = inboundChannel.writeAndFlush(resCodec); 

    cf.addListener(new ChannelFutureListener() { 

     @Override 
     public void operationComplete(ChannelFuture future) { 

      if (future.isSuccess()) { 
       inboundChannel.close(); 

      } else { 
       try { 
       // do Rollback Process B Here 
      } 
     } 
    }); 

Je pensais que c'est à cause du protocole TCP. Si le client se déconnecte normalement, le signal FIN est envoyé au serveur. Donc, il pense que writeAndFlush réussit d'une façon ou d'une autre même quand ce n'est pas le cas.

J'ai essayé code suivant aussi, mais ceux-ci ont le même résultat (renvoie toujours)

if(inboundChannel.isActive()){ 
     inboundChannel.writeAndFlush(msg); 
    } else{ 
     // do RollBack B 
    } 

    // Similar codes using inboundChannel.isOpen(), inboundChannel.isWritable() 

Ni l'événement « channelInactive » ni « Connexion réinitialisée par l'homologue » exception se produit dans mon cas.




Ceci est la partie du code client de test Netty que j'ai utilisée.

public void channelActive(ChannelHandlerContext ctx) { 
     ctx.writeAndFlush(message).addListener(ChannelFutureListener.CLOSE);   
    } 


Comment puis-je remarquer la déconnexion au moment où je veux répondre?

+0

C'est le même problème qui peut se produire dans le protocole SMTP, un serveur de messagerie a reçu le courrier, mais le client ne le sait jamais. L'un des moyens de résoudre ce problème est d'utiliser des numéros de transaction générés côté client et lorsque le client se reconnecte, demandez l'état de cet identifiant de transaction. – Ferrybig

+0

Vous ne devez pas tenter de restaurer même si vous détectez un client déconnecté. Il vous a dit d'effectuer la transaction, vous l'avez effectuée: vous ne pouvez pas le confirmer, mais c'est un problème, pas le vôtre. La solution consiste à concevoir vos transactions de manière à ce qu'elles soient * idempotentes *, c'est-à-dire que la réapplication d'une transaction déjà appliquée ne fasse rien. – EJP

Répondre

0

Il se peut que vous deviez remplacer la méthode ci-dessous et voir si le contrôle se passe ici lorsque le canal est fermé.

@Override 
public void channelInactive(ChannelHandlerContext ctx) throws Exception { 
    // write cleanup code 
} 

Je ne pense pas il est possible de suivre que si le client est connecté ou non Netty parce qu'il ya une abstraction entre Netty et client.

+0

Merci pour vos conseils mais cela ne fonctionne pas pour moi .. L'événement ChannelInactive ne coule pas dans pipleline jusqu'à ce que le serveur se ferme en appelant explicitement ctx.close(). –