Sono nuovo di Netty e ancora strugling di trovare la mia strada. Sto cercando di creare un client http che funzioni in modo asincrono. Gli esempi Netty di http mostrano solo come aspettare per le operazioni di IO, e non come utilizzare addListener, e così ho cercato di conoscere questo numero per gli ultimi giorni.client asincroni HTTP con Netty
Sto cercando di creare una classe richiesta che gestirà tutti i diversi stati di una richiesta, di connettersi, l'invio dei dati, la gestione della risposta e quindi la chiusura della connessione. Per fare ciò la mia classe si estende SimpleChannelUpstreamHandler e implementa ChannelFutureListener. Io uso uno ChannelPipelineFactory che aggiunge l'istanza (this) alla classe (come SimpleChannelUpstreamHandler) alla pipeline come gestore.
La connessione viene creata in questo modo:
this.state = State.Connecting;
this.clientBootstrap.connect(this.address).addListener(this);
Poi il metodo dioperationComplete:
@Override
public void operationComplete(ChannelFuture future) throws Exception {
State oldState = this.state;
if (!future.isSuccess()) {
this.status = Status.Failed;
future.getChannel().disconnect().addListener(this);
}
else if (future.isCancelled()) {
this.status = Status.Canceled;
future.getChannel().disconnect().addListener(this);
}
else switch (this.state) {
case Connecting:
this.state = State.Sending;
Channel channel = future.getChannel();
channel.write(this.createRequest()).addListener(this);
break;
case Sending:
this.state = State.Disconnecting;
future.getChannel().disconnect().addListener(this);
break;
case Disconnecting:
this.state = State.Closing;
future.getChannel().close().addListener(this);
break;
case Closing:
this.state = State.Finished;
break;
}
System.out.println("request operationComplete start state: " + oldState + ", end state: " + this.state + ", status: " + this.status);
}
private HttpRequest createRequest() {
String url = this.url.toString();
HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, url);
request.setHeader(HttpHeaders.Names.HOST, this.url.getHost());
request.setHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE);
request.setHeader(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP);
return request;
}
La classe ignora anche la messageReceived metodo:
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
System.out.println("messageReceived");
HttpResponse response = (HttpResponse) e.getMessage();
ChannelBuffer content = response.getContent();
if (content.readable()) {
System.out.println("CONTENT: " + content.toString(CharsetUtil.UTF_8));
}
}
Il problema è che ottengo questo output:
request operationComplete start state: Connecting, end state: Sending, status: Unknown
request operationComplete start state: Sending, end state: Disconnecting, status: Unknown
request operationComplete start state: Closing, end state: Finished, status: Unknown
request operationComplete start state: Disconnecting, end state: Finished, status: Unknown
Come si può vedere la messageReceived del non viene eseguito per qualche ragione, anche se la fabbrica gasdotto aggiunge l'istanza di questa classe per la pipeline.
Tutte le idee che mi manca qui? Grazie.
Modifica
sono riuscito ad ottenere finalmente questo grazie lavorano all'aiuto di @JestanNirojan, nel caso in cui qualcuno sarà interessato a una soluzione:
public class ClientRequest extends SimpleChannelUpstreamHandler {
....
public void connect() {
this.state = State.Connecting;
System.out.println(this.state);
this.clientBootstrap.connect(this.address);
}
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
this.state = State.Sending;
System.out.println(this.state);
ctx.getChannel().write(this.createRequest());
}
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
HttpResponse response = (HttpResponse) e.getMessage();
ChannelBuffer content = response.getContent();
if (content.readable()) {
System.out.println("CONTENT: " + content.toString(CharsetUtil.UTF_8));
}
this.state = State.Disconnecting;
System.out.println(this.state);
}
@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
this.state = State.Closing;
System.out.println(this.state);
}
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
this.state = State.Finished;
System.out.println(this.state);
}
private HttpRequest createRequest() {
String url = this.url.toString();
HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, url);
request.setHeader(HttpHeaders.Names.HOST, this.url.getHost());
request.setHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE);
request.setHeader(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP);
return request;
}
}
è HttpResponse la HttpResponse pieno o può essere un pezzo di TI?Ho 1000 di pezzi che tornano e voglio un evento per chunk o la memoria esploderà con conseguente esaurimento della memoria. –
HttpResponse è la risposta completa, non puoi ridurlo per quanto ne so. Dovresti andare più in basso, probabilmente con [HttpResponseDecoder] (http://static.netty.io/3.5/api/org/jboss/netty/handler/codec/http/HttpResponseDecoder.html). –
Se non sei interessato a chunking usa il client http chiaro qui @ https://github.com/arungeorge81/netty-http-client –