2017-09-12 5 views
0

私は、以下の条件を満たしてネッティーサーバーを作っています:それはそのクライアントからのパケットを受信したときクライアントが切断されたとき、Nettyサーバはどのように知っていますか?

  1. サーバは、トランザクション処理Aを行う必要があります。
  2. トランザクションが終了すると、まだ接続されていれば、クライアントに戻りメッセージを返します。そうでない場合は、いくつかのロールバックプロセスBを実行してください。

しかし、私の問題は、クライアントに返信すると、サーバはまだ接続されているかどうかを知りません。

メッセージを送信する前に、次のコードを試して接続を確認しました。しかし、クライアントがすでにソケットを閉じても常に成功します。クライアントプロセスが強制的に(例えば、Ctrl + Cを)殺害された場合にのみ、私はこれが原因でTCPプロトコルであると思っ

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 
      } 
     } 
    }); 

失敗しました。クライアントが正常に切断されると、FIN信号がサーバーに送信されます。それで、writeAndFlushは、それがしなくても何とか成功すると思います。

だから、例外が私の場合に発生する(常にtrueを返す)

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

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

どちらも「ピアによって接続リセット」「channelInactive」イベントもが、私はあまりにも、次のコードを試してみたが、これらは同じ結果を持っています。




これは私が使用したNettyテストクライアントコードの一部です。

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


どのように私は私が返信したい時に切断に気付くことができますか?

+0

これは、SMTPプロトコルで発生する可能性のある同じ問題です。メールサーバーはメールを受信しましたが、クライアントはそれを認識しません。これが解決できる方法の1つは、クライアント側で生成されたトランザクション番号を使用することです。クライアントが「再接続」すると、そのトランザクションIDに関する状態を尋ねます – Ferrybig

+0

切断されたクライアントを検出した場合でもロールバックを試みるべきではありません。彼はあなたにトランザクションを実行するように言った、あなたはそれを実行した:あなたは彼にそれを確認することはできませんが、それは問題ではなく、あなたのものです。その解決策は、トランザクションが*冪等であるように設計することです。つまり、既に適用されているトランザクションを再適用することは何もしません。 – EJP

答えて

0

以下のメソッドをオーバーライドして、チャンネルが閉じているときにコントロールがここに移動するかどうかを確認する必要があります。

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

私は、クライアントが網状に接続されているかどうかネッティーとクライアントの間の抽象化があるためことを追跡するために、その可能性はないと思います。

+0

あなたの助言をありがとう、それは私のために働いていません..サーバがctx.close()を明示的に呼び出すことによって閉じられるまで、ChannelInactiveイベントはpiplelineに流れません。 –

関連する問題