More robust pipeline manipulation while upgrading to WebSocket
- This commit allows a user to write its first web socket frame right after calling WebSocketServerHandshaker.handshake() rather than adding a listener to the future it returns. - Should fix #1933
This commit is contained in:
parent
3a01bf1064
commit
3367e51882
@ -159,33 +159,38 @@ public abstract class WebSocketServerHandshaker {
|
|||||||
logger.debug(String.format("%s WS Version %s server handshake", channel, version()));
|
logger.debug(String.format("%s WS Version %s server handshake", channel, version()));
|
||||||
}
|
}
|
||||||
FullHttpResponse response = newHandshakeResponse(req, responseHeaders);
|
FullHttpResponse response = newHandshakeResponse(req, responseHeaders);
|
||||||
|
ChannelPipeline p = channel.pipeline();
|
||||||
|
if (p.get(HttpObjectAggregator.class) != null) {
|
||||||
|
p.remove(HttpObjectAggregator.class);
|
||||||
|
}
|
||||||
|
if (p.get(HttpContentCompressor.class) != null) {
|
||||||
|
p.remove(HttpContentCompressor.class);
|
||||||
|
}
|
||||||
|
ChannelHandlerContext ctx = p.context(HttpRequestDecoder.class);
|
||||||
|
final String encoderName;
|
||||||
|
if (ctx == null) {
|
||||||
|
// this means the user use a HttpServerCodec
|
||||||
|
ctx = p.context(HttpServerCodec.class);
|
||||||
|
if (ctx == null) {
|
||||||
|
promise.setFailure(
|
||||||
|
new IllegalStateException("No HttpDecoder and no HttpServerCodec in the pipeline"));
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
p.addBefore(ctx.name(), "wsdecoder", newWebsocketDecoder());
|
||||||
|
p.addBefore(ctx.name(), "wsencoder", newWebSocketEncoder());
|
||||||
|
encoderName = ctx.name();
|
||||||
|
} else {
|
||||||
|
p.replace(ctx.name(), "wsdecoder", newWebsocketDecoder());
|
||||||
|
|
||||||
|
encoderName = p.context(HttpResponseEncoder.class).name();
|
||||||
|
p.addAfter(encoderName, "wsencoder", newWebSocketEncoder());
|
||||||
|
}
|
||||||
channel.writeAndFlush(response).addListener(new ChannelFutureListener() {
|
channel.writeAndFlush(response).addListener(new ChannelFutureListener() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
if (future.isSuccess()) {
|
if (future.isSuccess()) {
|
||||||
ChannelPipeline p = future.channel().pipeline();
|
ChannelPipeline p = future.channel().pipeline();
|
||||||
if (p.get(HttpObjectAggregator.class) != null) {
|
p.remove(encoderName);
|
||||||
p.remove(HttpObjectAggregator.class);
|
|
||||||
}
|
|
||||||
if (p.get(HttpContentCompressor.class) != null) {
|
|
||||||
p.remove(HttpContentCompressor.class);
|
|
||||||
}
|
|
||||||
ChannelHandlerContext ctx = p.context(HttpRequestDecoder.class);
|
|
||||||
if (ctx == null) {
|
|
||||||
// this means the user use a HttpServerCodec
|
|
||||||
ctx = p.context(HttpServerCodec.class);
|
|
||||||
if (ctx == null) {
|
|
||||||
promise.setFailure(
|
|
||||||
new IllegalStateException("No HttpDecoder and no HttpServerCodec in the pipeline"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p.addBefore(ctx.name(), "wsdecoder", newWebsocketDecoder());
|
|
||||||
p.replace(ctx.name(), "wsencoder", newWebSocketEncoder());
|
|
||||||
} else {
|
|
||||||
p.replace(ctx.name(), "wsdecoder", newWebsocketDecoder());
|
|
||||||
|
|
||||||
p.replace(HttpResponseEncoder.class, "wsencoder", newWebSocketEncoder());
|
|
||||||
}
|
|
||||||
promise.setSuccess();
|
promise.setSuccess();
|
||||||
} else {
|
} else {
|
||||||
promise.setFailure(future.cause());
|
promise.setFailure(future.cause());
|
||||||
|
Loading…
Reference in New Issue
Block a user