2016-01-22 12 views
5

クライアントからサーバーへのアプリケーション用のログインサーバーを作成しています。クライアントのサーバーからサーバーへの認証 - シングルスレッド

基本的に5台のサーバーがあり、これらのサーバーはすべて1台のログインサーバーに接続されています。

クライアントはこれらの5つのサーバーに接続できますが、ユーザー名とパスワードで認証する必要があります。ログインサーバーで認証を行う必要があります。ログインサーバーは、クライアントへの応答を返すべき実際のサーバーへの応答を返します。

だから、そのような:

クライアント - >サーバー - >ログイン・サーバー - >サーバー - >クライアント(応答コード)

さて、私はネッティーを使用していますが、それはNIOだ、それはスレッドではないですクライアントごとにNIOで認証するには、ログインサーバーからの応答が待つ必要があります。ログインに時間がかかり、他のクライアントが遅れることがあります。 。だから、私はそれをどのように機能させるかという考えを考えました。私のアイデアは別のスレッドでリクエストを実行し、onResponse(String key, int responseCode)メソッドでイベントを持っていて、生成されたキーを持つマップにクライアントのチャンネルを入れて、レスポンスの所属を知ることができます。したがって、私たちが認証すると、鍵とユーザーのデータを送信します。

しかし、私はこれが悪い方法であり、これを行うためのより効率的な方法があると感じています。何か案は?

+0

AFAIK nettyは、接続ごとにスレッドでNIOをブロックすることをサポートしています。 NIOの* default *動作はブロック動作であり、最近までSocketだけがオプションとして非ブロック動作をサポートしていました。 –

+0

マルチサーバー環境では、マップを使用してチャネルを保持すると、そのマップが破損します。 – eg04lt3r

+0

これを行うためのより良い方法を尋ねたので、ちょっとお勧めします.Javaを使用している場合は、Webソケット(html 5 + http(s))を調べるとよいでしょう。次に、クライアントモデルごとにスレッドを処理し、暗号化を使用した認証はアプリケーションに透過的で、エンドクライアントを配置しないNIOのすべての機能を利用できます。 – MuffinMan

答えて

2

あなたはすべてのシステムの完全な制御を持っていると仮定すると:

は、サーバ内の各クライアント接続のためのIDを割り当てます。次に、ユーザーを認証する必要があるときに、サーバーからログインサーバーへの要求にこの接続IDを含め、ログインサーバーからの応答を待たずに戻ります。

今後、サーバーはログインサーバーからのログイン応答を受信します。ログイン応答にクライアント接続IDが含まれている場合は、そのIDを使用してサーバーからクライアントへの接続を検索し、その応答をクライアントに中継します。

1

ここで私はそれをしました。あなたはどのクライアントに属しているチャネルを識別することができるよう

セットアップは、チャンネルのラッパークラスを作成します。

public class CustomChannel implements Channel { 

    private final Channel channel; 
    private final String clientId; 

    ... 
} 

クライアントのチャネルマッチング用のカスタムChannelMatcher作成します。クライアント・ハンドラで

要求を処理

public class CustomChannelMatcher implements ChannelMatcher { 
    private final String clientId; 

    public CustomChannelMatcher(String clientId) { 
     this.clientId = clientId; 
    } 

    @Override 
    public boolean matches(Channel channel) { 
     if (channel instanceof CustomChannel) { 
      return clientId.equals(((CustomChannel) channel).getClientId()); 
     } 
     return false; 
    } 

    ... 
} 

を、あなたのクライアントのチャンネルを追跡するためにチャネル・グループを使用します。応答サーバーハンドラで

、クライアントのチャンネルに合わせてCustomChannelMatcherを使うの取り扱い

ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); 

... 

channelGroup.add(new CustomChannel(ctx.channel(), clientId)); 

// send request to another server without blocking 

上記のコードは、一致するクライアントのチャネルを見つけてメッセージを書き込みます。

1

あなたはNIOワーカースレッドをブロックすることが心配ですが、別のスレッドを回してログインを実行します。とにかくもう1つのスレッドを使用しました。したがって、http(s)用にサーバー内にさらに多くのスレッドを定義し、それを使って処理します。 100を超える同時ログインが予想されない限り、ここに問題はありません。

NIOは過大評価されています。 OSはスレッドとコンテキストの切り替えをスケジューリングするのに優れています。asyn apisでバックプラグをやっているJavaよりはるかに優れています。待機中のスレッドはCPUを消費しません。

0

あなたはあなたがNettyにいると言っています。

これは、Servlet API 3.0以降で問題が解決されています。このサーブレットAPIを使用すると、AsynContextで正確にその作業を実行できます。冗談ではなく、サーブレット3.0、好ましくはjavaone youtubeのプレゼンテーションとチュートリアルを読んでください。PDF仕様でもjavadocより優れています。

サーブレット入力ストリーム/サーブレット出力ストリームでNIOを実行したい場合でも、サーブレットAPI 3.1でこれを行うことができます。私が思うに、2020年のJavaのプレゼンテーションは素晴らしかったです。

関連する問題