2012-01-28 9 views
8

私はほとんどがNettyにありますが、1つのコンセプトはまだ私を暗示しており、チュートリアルなどで何も見つかりません。まず、Nettyは非同期であることを理解していますが、クライアントがサーバーを呼び出し、ハンドラを超えて応答を得る方法が必要です。私はもっ​​と説明しましょう。Netty - クライアントでサーバレスポンスを取得する方法

私は以下のようにクライアントを持っています。そして、私はそれがブートストラップされていることを理解していることに注意してください、そして、それぞれの呼び出しで新しい接続が確立されます、それは例をより小さくそしてより簡潔にするためだけです。その事実を無視してください。

Client.java

// ServerResponse is a result from the server, in this case 
// a list of users of the system (ignore that each time it's all bootstrapped). 

public User[] callServerForInformationFromGUIWidget() 
{ 
    ClientBootstrap bootstrap = new ClientBootstrap(...); 
    bootstrap.setPipelineFactory(...); 

    ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port)); 
    Channel channel = future.awaitUninterruptibly().getChannel(); 

    // Where request is a POJO sent to the server, 
    // with a request such as get me a list of users 
    RequestPojo request = new RequestPojo(requestUserListCommand); 

    ChannelFuture lastWriteFuture = channel.write(request); 

    if(lastWriteFuture != null) 
     lastWriteFuture.awaitUninterruptibly(); 
} 

今私は、サーバー上のデータを取得し、その結果を反撃する方法を理解します。唯一のことは、クライアント側でどのように処理するのですか?

ClientHandler.java問題は、クライアントコードが実際にその結果を取得しない方法です

@Override 
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) 
{ 
    User[] users = (User[])e.getMessage(); 
} 

:はいClientHandlerのクラスには、次のような何かを行うことができますか?すべての例はチャットサービスと似ています。チャットサービスでは、レスポンスを待機していないクライアント上でイベントが発生します。私が見つけたHTTPクライアントの例でさえ、これは欠けています。ドキュメント全体は本当に良いですが、コールバックを行う方法が欠けています。とにかく、この場合、サーバーからの応答を得るためにクライアントが必要であり、結果に基づいて必要な処理を行います。ハンドラが答えを探している、あるいは誰がいる人を知りませんので

IdealClient.java

// ServerResponse is a result from the server, in this case 
// a list of users of the system. 

public User[] callServerForInformationFromGUIWidget() 
{ 
    ... 
    RequestPojo request = new RequestPojo(requestUserListCommand); 
    ChannelFuture lastWriteFuture = channel.write(request); 

    if(lastWriteFuture != null) 
     lastWriteFuture.awaitUninterruptibly(); 

    User[] users = resultFromCallToServer(); 

    performSomeAction(users); 
} 

:私はこのような何かを行うには、クライアントを書くのですか

つまり

、質問をしました。そして、それがハンドラで行われている場合、どのように?

例についての私のコメントに戻って、httpクライアント(およびハンドラ)の例では、結果がSystem.outにダンプされます。 GUIを持っていたら、どのようにあなたの要求からの結果をGUIに渡すのですか?私はこれの例を見たことがありません。

答えて

5

ジェスタンが正しい。私の場合は、顧客に価格ティックデータを処理する必要があります。私は解析のためにAntlrを使用します。パーサーでイベントを発生させますが、私の場合、私のプロトコルはStringベースです。以下はAntlrを除いた例です。あなたのケースでStringメッセージを渡すのはユーザーかもしれません。

//----------------- Event -------------- 
public class DataChangeEvent { 
    private String message; 

    public DataChangeEvent(String message) { 
     this.message = message; 
    } 

    public String getMessage() { 
     return message; 
    } 


} 

//----------------- Listener -------------- 
public interface DataChangeListenter { 
    public void dataChangeEvent(DataChangeEvent event); 
} 

//----------------- Event Handler that fires the dataChange events -------------- 
// This class needs to be static since you need to register all your classes that want to be notified of data change events 
public class DataChangedHandler { 
    private static List<DataChangeListenter> listeners = new ArrayList<DataChangeListenter>(); 

    public static void registerDataChangeListener(DataChangeListenter listener) { 
     listeners.add(listener); 
    } 

    public static void fireDataChange(DataChangeEvent dataChangeEvent) { 
     for(DataChangeListenter listenter : listeners) { 
      listenter.dataChangeEvent(dataChangeEvent); 
     } 
    } 
} 

//----------------- Example class that implements the listener and registers itself for events -------------- 
public class ProcessMessage implements DataChangeListenter { 

    public ProcessMessage() { 
     DataChangedHandler.registerDataChangeListener(this); 
    } 

    public void dataChangeEvent(DataChangeEvent event) { 
     //Depending on your protocal, I use Antlr to parse my message 
     System.out.println(event.getMessage()); 
    } 


} 

//---------------- Netty Handler ----------- 
public class TelnetClientHandler extends SimpleChannelHandler { 

    private static final Logger logger = Logger.getLogger(TelnetClientHandler.class.getName()); 

    @Override 
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { 
     String message = (String) e.getMessage(); 
     DataChangedHandler.fireDataChange(message); 
    } 
} 
+0

リスナー登録のガイドラインに従っていますが、「互換性のない型があります:文字列をDataChangeEventに変換できません」...何が問題なのですか?どうも。 – Phobox

1

メッセージハンドラでmessageReceived()を使用して処理する必要があります。あなたの問題が正確であるか分かりません。私の推測では、どのような要求がなされたかに応じて変化する要求に対する応答がありますか?たぶんあなたが何を要求しているのかを知っておかなければならない応答をしていることの具体的な説明。あなたが行うことができるかもしれない1つの事は、未解決の要求を知っているハンドラに長い生きたオブジェクトを渡すことです。応答を受け取ったときにそれを一致させることができます。パイプラインファクトリメソッドは、マネージャ型オブジェクトへの参照をハンドラに渡すことができます。

これは私が言っていることとほとんど同じでした。あなたのハンドラは、そこからハンドラにパラメータを渡すことは容易であるPipelineFactoryに作成されます。あなたはあなたのパイプラインを作成するとき

bootstrap.setPipelineFactory(new ChannelPipelineFactory() { 
     public ChannelPipeline getPipeline() throws Exception { 
      ChannelPipeline pipeline = Channels.pipeline(); 

      pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.nulDelimiter())); 
      pipeline.addLast("decoder", new XMLDecoder()); 
      pipeline.addLast("encoder", new XMLEncoder()); 
      // notice here I'm passing two objects to the Handler so it can 
      // call the UI. 
      pipeline.addLast("handler", new MyHandler(param1, param2)); 

      return pipeline; 
     } 
    }); 

あなたは新しい接続時に、あなたのハンドラを追加します。 1つまたは複数のオブジェクトを渡すだけで、UIまたはコントローラに再度通信することができます。

+0

たとえば、httpクライアントの例では、結果は単にSystem.outにダンプされます。結果を渡さなければならなかったGUIを持っていたら?たとえば、ハンドラが認識していないJTextArea、またはJDialogなどに渡されなければなりませんでした。つまり、JButtonが押され、イベントがクライアントを介してサーバーを呼び出します。どのようにして基本的にサーバーからの結果をJButtonの呼び出しメソッドに戻しますか? –

+0

JButtonハンドラがJTextAreaに結果を表示する可能性があるため、おそらくJDialogなどになる可能性があります。 –

+1

hotpottao asychモードhttp://hotpotato.biasedbit.comのように、コールバック(リスナー)を使用して応答を処理します。 /、(Nettyも使用しています)、messageReceived :)の中でそれを処理する必要があります。この種のコールバックは、プロトコル/アプリケーションがより具体的であるため、デフォルトでは提供されません。 –

関連する問題