Upgrade connection after completed response

Channel handlers above the HttpEncoder may delay the repsonse being
written to the socket. We need to wait for the response to complete
before upgrading the pipeline.
This commit is contained in:
Jeff Smick 2012-09-09 08:50:31 -07:00
parent f9afd7d44b
commit 324ba369e0
6 changed files with 66 additions and 25 deletions

View File

@ -23,6 +23,8 @@ import java.util.Map;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
@ -185,7 +187,13 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
ChannelFuture future = channel.write(request);
channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket00FrameEncoder());
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
ChannelPipeline p = future.getChannel().getPipeline();
p.replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket00FrameEncoder());
}
});
return future;
}

View File

@ -20,6 +20,8 @@ import java.util.Map;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
@ -171,7 +173,13 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
ChannelFuture future = channel.write(request);
channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket08FrameEncoder(true));
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
ChannelPipeline p = future.getChannel().getPipeline();
p.replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket08FrameEncoder(true));
}
});
return future;
}

View File

@ -20,6 +20,8 @@ import java.util.Map;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
@ -167,7 +169,13 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
ChannelFuture future = channel.write(request);
channel.getPipeline().replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket13FrameEncoder(true));
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
ChannelPipeline p = future.getChannel().getPipeline();
p.replace(HttpRequestEncoder.class, "ws-encoder", new WebSocket13FrameEncoder(true));
}
});
return future;
}

View File

@ -23,6 +23,7 @@ import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
@ -184,17 +185,23 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
}
}
// Upgrade the connection and send the handshake response.
ChannelPipeline p = channel.getPipeline();
if (p.get(HttpChunkAggregator.class) != null) {
p.remove(HttpChunkAggregator.class);
}
p.replace(HttpRequestDecoder.class, "wsdecoder",
new WebSocket00FrameDecoder(getMaxFramePayloadLength()));
ChannelFuture future = channel.write(res);
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket00FrameEncoder());
// Upgrade the connection and send the handshake response.
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
ChannelPipeline p = future.getChannel().getPipeline();
if (p.get(HttpChunkAggregator.class) != null) {
p.remove(HttpChunkAggregator.class);
}
p.replace(HttpRequestDecoder.class, "wsdecoder",
new WebSocket00FrameDecoder(getMaxFramePayloadLength()));
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket00FrameEncoder());
}
});
return future;
}

View File

@ -170,14 +170,19 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
ChannelFuture future = channel.write(res);
// Upgrade the connection and send the handshake response.
ChannelPipeline p = channel.getPipeline();
if (p.get(HttpChunkAggregator.class) != null) {
p.remove(HttpChunkAggregator.class);
}
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
ChannelPipeline p = future.getChannel().getPipeline();
if (p.get(HttpChunkAggregator.class) != null) {
p.remove(HttpChunkAggregator.class);
}
p.replace(HttpRequestDecoder.class, "wsdecoder",
new WebSocket08FrameDecoder(true, allowExtensions, getMaxFramePayloadLength()));
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket08FrameEncoder(false));
p.replace(HttpRequestDecoder.class, "wsdecoder",
new WebSocket08FrameDecoder(true, allowExtensions, getMaxFramePayloadLength()));
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket08FrameEncoder(false));
}
});
return future;
}

View File

@ -177,14 +177,19 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
ChannelFuture future = channel.write(res);
// Upgrade the connection and send the handshake response.
ChannelPipeline p = channel.getPipeline();
if (p.get(HttpChunkAggregator.class) != null) {
p.remove(HttpChunkAggregator.class);
}
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
ChannelPipeline p = future.getChannel().getPipeline();
if (p.get(HttpChunkAggregator.class) != null) {
p.remove(HttpChunkAggregator.class);
}
p.replace(HttpRequestDecoder.class, "wsdecoder",
new WebSocket13FrameDecoder(true, allowExtensions, getMaxFramePayloadLength()));
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket13FrameEncoder(false));
p.replace(HttpRequestDecoder.class, "wsdecoder",
new WebSocket13FrameDecoder(true, allowExtensions, getMaxFramePayloadLength()));
p.replace(HttpResponseEncoder.class, "wsencoder", new WebSocket13FrameEncoder(false));
}
});
return future;
}