Example usage for io.netty.channel ChannelPromise addListener

List of usage examples for io.netty.channel ChannelPromise addListener

Introduction

In this page you can find the example usage for io.netty.channel ChannelPromise addListener.

Prototype

@Override
    ChannelPromise addListener(GenericFutureListener<? extends Future<? super Void>> listener);

Source Link

Usage

From source file:com.relayrides.pushy.apns.ApnsClientHandler.java

License:Open Source License

@Override
public void write(final ChannelHandlerContext context, final Object message, final ChannelPromise writePromise)
        throws Http2Exception {
    if (message instanceof PushNotificationAndResponsePromise) {
        final PushNotificationAndResponsePromise pushNotificationAndResponsePromise = (PushNotificationAndResponsePromise) message;

        final ApnsPushNotification pushNotification = pushNotificationAndResponsePromise.getPushNotification();

        if (this.responsePromises.containsKey(pushNotification)) {
            writePromise.tryFailure(new PushNotificationStillPendingException());
        } else {// www.  ja  v  a  2 s  .c  o  m
            this.responsePromises.put(pushNotification,
                    pushNotificationAndResponsePromise.getResponsePromise());

            pushNotificationAndResponsePromise.getResponsePromise().addListener(
                    new GenericFutureListener<Future<PushNotificationResponse<ApnsPushNotification>>>() {

                        @Override
                        public void operationComplete(
                                final Future<PushNotificationResponse<ApnsPushNotification>> future) {
                            // Regardless of the outcome, when the response promise is finished, we want to remove it from
                            // the map of pending promises.
                            ApnsClientHandler.this.responsePromises.remove(pushNotification);
                        }
                    });

            this.write(context, pushNotification, writePromise);
        }
    } else if (message instanceof ApnsPushNotification) {
        final ApnsPushNotification pushNotification = (ApnsPushNotification) message;

        try {
            final int streamId = (int) this.nextStreamId;

            final Http2Headers headers = new DefaultHttp2Headers().method(HttpMethod.POST.asciiName())
                    .authority(this.authority).path(APNS_PATH_PREFIX + pushNotification.getToken())
                    .addInt(APNS_EXPIRATION_HEADER, pushNotification.getExpiration() == null ? 0
                            : (int) (pushNotification.getExpiration().getTime() / 1000));

            final String authenticationToken = this.apnsClient
                    .getAuthenticationTokenSupplierForTopic(pushNotification.getTopic()).getToken();
            headers.add(APNS_AUTHORIZATION_HEADER, "bearer " + authenticationToken);

            if (pushNotification.getCollapseId() != null) {
                headers.add(APNS_COLLAPSE_ID_HEADER, pushNotification.getCollapseId());
            }

            if (pushNotification.getPriority() != null) {
                headers.addInt(APNS_PRIORITY_HEADER, pushNotification.getPriority().getCode());
            }

            if (pushNotification.getTopic() != null) {
                headers.add(APNS_TOPIC_HEADER, pushNotification.getTopic());
            }

            final ChannelPromise headersPromise = context.newPromise();
            this.encoder().writeHeaders(context, streamId, headers, 0, false, headersPromise);
            log.trace("Wrote headers on stream {}: {}", streamId, headers);

            final ByteBuf payloadBuffer = context.alloc().ioBuffer(INITIAL_PAYLOAD_BUFFER_CAPACITY);
            payloadBuffer.writeBytes(pushNotification.getPayload().getBytes(StandardCharsets.UTF_8));

            final ChannelPromise dataPromise = context.newPromise();
            this.encoder().writeData(context, streamId, payloadBuffer, 0, true, dataPromise);
            log.trace("Wrote payload on stream {}: {}", streamId, pushNotification.getPayload());

            final PromiseCombiner promiseCombiner = new PromiseCombiner();
            promiseCombiner.addAll(headersPromise, dataPromise);
            promiseCombiner.finish(writePromise);

            writePromise.addListener(new GenericFutureListener<ChannelPromise>() {

                @Override
                public void operationComplete(final ChannelPromise future) throws Exception {
                    if (future.isSuccess()) {
                        ApnsClientHandler.this.pushNotificationsByStreamId.put(streamId, pushNotification);
                        ApnsClientHandler.this.authenticationTokensByStreamId.put(streamId,
                                authenticationToken);
                    } else {
                        log.trace("Failed to write push notification on stream {}.", streamId, future.cause());

                        final Promise<PushNotificationResponse<ApnsPushNotification>> responsePromise = ApnsClientHandler.this.responsePromises
                                .get(pushNotification);

                        if (responsePromise != null) {
                            responsePromise.tryFailure(future.cause());
                        } else {
                            log.error("Notification write failed, but no response promise found.");
                        }
                    }
                }
            });

            this.nextStreamId += 2;

            if (this.nextStreamId >= STREAM_ID_RESET_THRESHOLD) {
                // This is very unlikely, but in the event that we run out of stream IDs (the maximum allowed is
                // 2^31, per https://httpwg.github.io/specs/rfc7540.html#StreamIdentifiers), we need to open a new
                // connection. Just closing the context should be enough; automatic reconnection should take things
                // from there.
                context.close();
            }
        } catch (NoKeyForTopicException | SignatureException e) {
            writePromise.tryFailure(e);
        }

    } else {
        // This should never happen, but in case some foreign debris winds up in the pipeline, just pass it through.
        log.error("Unexpected object in pipeline: {}", message);
        context.write(message, writePromise);
    }
}

From source file:com.turo.pushy.apns.ApnsClientHandler.java

License:Open Source License

private void writePushNotification(final ChannelHandlerContext context,
        final PushNotificationPromise responsePromise, final ChannelPromise writePromise) {
    if (context.channel().isActive()) {
        final int streamId = this.connection().local().incrementAndGetNextStreamId();

        if (streamId > 0) {
            // We'll attach the push notification and response promise to the stream as soon as the stream is created.
            // Because we're using a StreamBufferingEncoder under the hood, there's no guarantee as to when the stream
            // will actually be created, and so we attach these in the onStreamAdded listener to make sure everything
            // is happening in a predictable order.
            this.unattachedResponsePromisesByStreamId.put(streamId, responsePromise);
            final ApnsPushNotification pushNotification = responsePromise.getPushNotification();

            final Http2Headers headers = getHeadersForPushNotification(pushNotification, streamId);

            final ChannelPromise headersPromise = context.newPromise();
            this.encoder().writeHeaders(context, streamId, headers, 0, false, headersPromise);
            log.trace("Wrote headers on stream {}: {}", streamId, headers);

            final ByteBuf payloadBuffer = context.alloc().ioBuffer(INITIAL_PAYLOAD_BUFFER_CAPACITY);
            payloadBuffer.writeBytes(pushNotification.getPayload().getBytes(StandardCharsets.UTF_8));

            final ChannelPromise dataPromise = context.newPromise();
            this.encoder().writeData(context, streamId, payloadBuffer, 0, true, dataPromise);
            log.trace("Wrote payload on stream {}: {}", streamId, pushNotification.getPayload());

            final PromiseCombiner promiseCombiner = new PromiseCombiner();
            promiseCombiner.addAll((ChannelFuture) headersPromise, dataPromise);
            promiseCombiner.finish(writePromise);

            writePromise.addListener(new GenericFutureListener<ChannelPromise>() {

                @Override/*from  w  w  w  .j a v  a 2 s. c  o  m*/
                public void operationComplete(final ChannelPromise future) {
                    if (!future.isSuccess()) {
                        log.trace("Failed to write push notification on stream {}.", streamId, future.cause());
                        responsePromise.tryFailure(future.cause());
                    }
                }
            });
        } else {
            // This is very unlikely, but in the event that we run out of stream IDs, we need to open a new
            // connection. Just closing the context should be enough; automatic reconnection should take things
            // from there.
            writePromise.tryFailure(STREAMS_EXHAUSTED_EXCEPTION);
            context.channel().close();
        }
    } else {
        writePromise.tryFailure(STREAM_CLOSED_BEFORE_REPLY_EXCEPTION);
    }
}

From source file:com.twitter.http2.HttpConnectionHandler.java

License:Apache License

@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
    if (msg instanceof HttpDataFrame) {

        HttpDataFrame httpDataFrame = (HttpDataFrame) msg;
        int streamId = httpDataFrame.getStreamId();

        // Frames must not be sent on half-closed streams
        if (httpConnection.isLocalSideClosed(streamId)) {
            promise.setFailure(PROTOCOL_EXCEPTION);
            return;
        }//from   w w w  .  java2 s. c  om

        // HTTP/2 DATA frame flow control processing requirements:
        //
        // Sender must not send a data frame with data length greater
        // than the transfer window size.
        //
        // After sending each data frame, the sender decrements its
        // transfer window size by the amount of data transmitted.
        //
        // When the window size becomes less than or equal to 0, the
        // sender must pause transmitting data frames.

        int dataLength = httpDataFrame.content().readableBytes();
        int sendWindowSize = httpConnection.getSendWindowSize(streamId);
        int connectionSendWindowSize = httpConnection.getSendWindowSize(HTTP_CONNECTION_STREAM_ID);
        sendWindowSize = Math.min(sendWindowSize, connectionSendWindowSize);

        if (sendWindowSize <= 0) {
            // Stream is stalled -- enqueue Data frame and return
            httpConnection.putPendingWrite(streamId, new HttpConnection.PendingWrite(httpDataFrame, promise));
            return;
        } else if (sendWindowSize < dataLength) {
            // Stream is not stalled but we cannot send the entire frame
            httpConnection.updateSendWindowSize(streamId, -1 * sendWindowSize);
            httpConnection.updateSendWindowSize(HTTP_CONNECTION_STREAM_ID, -1 * sendWindowSize);

            // Create a partial data frame whose length is the current window size
            ByteBuf data = httpDataFrame.content().readSlice(sendWindowSize);
            ByteBuf partialDataFrame = httpFrameEncoder.encodeDataFrame(streamId, false, data);

            // Enqueue the remaining data (will be the first frame queued)
            httpConnection.putPendingWrite(streamId, new HttpConnection.PendingWrite(httpDataFrame, promise));

            ChannelPromise writeFuture = ctx.channel().newPromise();

            // The transfer window size is pre-decremented when sending a data frame downstream.
            // Close the connection on write failures that leaves the transfer window in a corrupt state.
            writeFuture.addListener(connectionErrorListener);

            ctx.write(partialDataFrame, writeFuture);
            return;
        } else {
            // Window size is large enough to send entire data frame
            httpConnection.updateSendWindowSize(streamId, -1 * dataLength);
            httpConnection.updateSendWindowSize(HTTP_CONNECTION_STREAM_ID, -1 * dataLength);

            // The transfer window size is pre-decremented when sending a data frame downstream.
            // Close the connection on write failures that leaves the transfer window in a corrupt state.
            promise.addListener(connectionErrorListener);
        }

        // Close the local side of the stream if this is the last frame
        if (httpDataFrame.isLast()) {
            halfCloseStream(streamId, false, promise);
        }

        ByteBuf frame = httpFrameEncoder.encodeDataFrame(streamId, httpDataFrame.isLast(),
                httpDataFrame.content());
        ctx.write(frame, promise);

    } else if (msg instanceof HttpHeadersFrame) {

        HttpHeadersFrame httpHeadersFrame = (HttpHeadersFrame) msg;
        int streamId = httpHeadersFrame.getStreamId();

        if (streamId <= lastStreamId) {
            // Frames must not be sent on half-closed (local) or closed streams
            if (httpConnection.isLocalSideClosed(streamId)) {
                promise.setFailure(PROTOCOL_EXCEPTION);
                return;
            }
        } else {
            if (isRemoteInitiatedId(streamId)) {
                promise.setFailure(PROTOCOL_EXCEPTION);
                return;
            }
            // Try to accept the stream
            boolean exclusive = httpHeadersFrame.isExclusive();
            int dependency = httpHeadersFrame.getDependency();
            int weight = httpHeadersFrame.getWeight();
            if (!acceptStream(streamId, exclusive, dependency, weight)) {
                promise.setFailure(PROTOCOL_EXCEPTION);
                return;
            }
        }

        // Close the local side of the stream if this is the last frame
        if (httpHeadersFrame.isLast()) {
            halfCloseStream(streamId, false, promise);
        }

        synchronized (httpHeaderBlockEncoder) {
            ByteBuf frame = httpFrameEncoder.encodeHeadersFrame(httpHeadersFrame.getStreamId(),
                    httpHeadersFrame.isLast(), httpHeadersFrame.isExclusive(), httpHeadersFrame.getDependency(),
                    httpHeadersFrame.getWeight(), httpHeaderBlockEncoder.encode(ctx, httpHeadersFrame));
            // Writes of compressed data must occur in order
            ctx.write(frame, promise);
        }

    } else if (msg instanceof HttpPriorityFrame) {

        HttpPriorityFrame httpPriorityFrame = (HttpPriorityFrame) msg;
        int streamId = httpPriorityFrame.getStreamId();
        boolean exclusive = httpPriorityFrame.isExclusive();
        int dependency = httpPriorityFrame.getDependency();
        int weight = httpPriorityFrame.getWeight();
        setPriority(streamId, exclusive, dependency, weight);
        ByteBuf frame = httpFrameEncoder.encodePriorityFrame(streamId, exclusive, dependency, weight);
        ctx.write(frame, promise);

    } else if (msg instanceof HttpRstStreamFrame) {

        HttpRstStreamFrame httpRstStreamFrame = (HttpRstStreamFrame) msg;
        removeStream(httpRstStreamFrame.getStreamId(), promise);
        ByteBuf frame = httpFrameEncoder.encodeRstStreamFrame(httpRstStreamFrame.getStreamId(),
                httpRstStreamFrame.getErrorCode().getCode());
        ctx.write(frame, promise);

    } else if (msg instanceof HttpSettingsFrame) {

        // TODO(jpinner) currently cannot have more than one settings frame outstanding at a time

        HttpSettingsFrame httpSettingsFrame = (HttpSettingsFrame) msg;
        if (httpSettingsFrame.isAck()) {
            // Cannot send an acknowledgement frame
            promise.setFailure(PROTOCOL_EXCEPTION);
            return;
        }

        int newHeaderTableSize = httpSettingsFrame.getValue(HttpSettingsFrame.SETTINGS_HEADER_TABLE_SIZE);
        if (newHeaderTableSize >= 0) {
            headerTableSize = newHeaderTableSize;
            changeDecoderHeaderTableSize = true;
        }

        int newConcurrentStreams = httpSettingsFrame
                .getValue(HttpSettingsFrame.SETTINGS_MAX_CONCURRENT_STREAMS);
        if (newConcurrentStreams >= 0) {
            localConcurrentStreams = newConcurrentStreams;
        }

        int newInitialWindowSize = httpSettingsFrame.getValue(HttpSettingsFrame.SETTINGS_INITIAL_WINDOW_SIZE);
        if (newInitialWindowSize >= 0) {
            updateInitialReceiveWindowSize(newInitialWindowSize);
        }

        ByteBuf frame = httpFrameEncoder.encodeSettingsFrame(httpSettingsFrame);
        ctx.write(frame, promise);

    } else if (msg instanceof HttpPushPromiseFrame) {

        if (!pushEnabled) {
            promise.setFailure(PROTOCOL_EXCEPTION);
            return;
        }

        // TODO(jpinner) handle push promise frames
        promise.setFailure(PROTOCOL_EXCEPTION);

        //      synchronized (httpHeaderBlockEncoder) {
        //        HttpPushPromiseFrame httpPushPromiseFrame = (HttpPushPromiseFrame) msg;
        //        ChannelBuffer frame = httpFrameEncoder.encodePushPromiseFrame(
        //            httpPushPromiseFrame.getStreamId(),
        //            httpPushPromiseFrame.getPromisedStreamId(),
        //            httpHeaderBlockEncoder.encode(ctx, httpPushPromiseFrame)
        //        );
        //        // Writes of compressed data must occur in order
        //        Channels.write(ctx, e.getFuture(), frame, e.getRemoteAddress());
        //      }

    } else if (msg instanceof HttpPingFrame) {

        HttpPingFrame httpPingFrame = (HttpPingFrame) msg;
        if (httpPingFrame.isPong()) {
            // Cannot send a PONG frame
            promise.setFailure(PROTOCOL_EXCEPTION);
        } else {
            ByteBuf frame = httpFrameEncoder.encodePingFrame(httpPingFrame.getData(), false);
            ctx.write(frame, promise);
        }

    } else if (msg instanceof HttpGoAwayFrame) {

        // Why is this being sent? Intercept it and fail the write.
        // Should have sent a CLOSE ChannelStateEvent
        promise.setFailure(PROTOCOL_EXCEPTION);

    } else if (msg instanceof HttpWindowUpdateFrame) {

        HttpWindowUpdateFrame httpWindowUpdateFrame = (HttpWindowUpdateFrame) msg;
        int streamId = httpWindowUpdateFrame.getStreamId();

        if (handleStreamWindowUpdates || streamId == HTTP_CONNECTION_STREAM_ID) {
            // Why is this being sent? Intercept it and fail the write.
            promise.setFailure(PROTOCOL_EXCEPTION);
        } else {
            int windowSizeIncrement = httpWindowUpdateFrame.getWindowSizeIncrement();
            httpConnection.updateReceiveWindowSize(streamId, windowSizeIncrement);
            ByteBuf frame = httpFrameEncoder.encodeWindowUpdateFrame(streamId, windowSizeIncrement);
            ctx.write(frame, promise);
        }

    } else {

        ctx.write(msg, promise);
    }
}

From source file:com.twitter.http2.HttpConnectionHandler.java

License:Apache License

private void updateSendWindowSize(ChannelHandlerContext ctx, int streamId, int windowSizeIncrement) {
    httpConnection.updateSendWindowSize(streamId, windowSizeIncrement);

    while (true) {
        // Check if we have unblocked a stalled stream
        HttpConnection.PendingWrite e = httpConnection.getPendingWrite(streamId);
        if (e == null) {
            break;
        }//from w w w  .  j a v a 2s .c  om

        HttpDataFrame httpDataFrame = e.httpDataFrame;
        int dataFrameSize = httpDataFrame.content().readableBytes();
        int writeStreamId = httpDataFrame.getStreamId();
        int sendWindowSize = httpConnection.getSendWindowSize(writeStreamId);
        int connectionSendWindowSize = httpConnection.getSendWindowSize(HTTP_CONNECTION_STREAM_ID);
        sendWindowSize = Math.min(sendWindowSize, connectionSendWindowSize);

        if (sendWindowSize <= 0) {
            return;
        } else if (sendWindowSize < dataFrameSize) {
            // We can send a partial frame
            httpConnection.updateSendWindowSize(writeStreamId, -1 * sendWindowSize);
            httpConnection.updateSendWindowSize(HTTP_CONNECTION_STREAM_ID, -1 * sendWindowSize);

            // Create a partial data frame whose length is the current window size
            ByteBuf data = httpDataFrame.content().readSlice(sendWindowSize);
            ByteBuf partialDataFrame = httpFrameEncoder.encodeDataFrame(writeStreamId, false, data);

            ChannelPromise writeFuture = ctx.channel().newPromise();

            // The transfer window size is pre-decremented when sending a data frame downstream.
            // Close the connection on write failures that leaves the transfer window in a corrupt state.
            writeFuture.addListener(connectionErrorListener);

            ctx.writeAndFlush(partialDataFrame, writeFuture);
        } else {
            // Window size is large enough to send entire data frame
            httpConnection.removePendingWrite(writeStreamId);
            httpConnection.updateSendWindowSize(writeStreamId, -1 * dataFrameSize);
            httpConnection.updateSendWindowSize(HTTP_CONNECTION_STREAM_ID, -1 * dataFrameSize);

            // The transfer window size is pre-decremented when sending a data frame downstream.
            // Close the connection on write failures that leaves the transfer window in a corrupt state.
            e.promise.addListener(connectionErrorListener);

            // Close the local side of the stream if this is the last frame
            if (httpDataFrame.isLast()) {
                halfCloseStream(writeStreamId, false, e.promise);
            }

            ByteBuf frame = httpFrameEncoder.encodeDataFrame(writeStreamId, httpDataFrame.isLast(),
                    httpDataFrame.content());

            ctx.writeAndFlush(frame, e.promise);
        }
    }
}

From source file:com.twitter.http2.HttpStreamEncoder.java

License:Apache License

private ChannelPromise getMessageFuture(final ChannelHandlerContext ctx, final ChannelPromise promise,
        final int streamId, HttpMessage message) {
    if (message instanceof StreamedHttpMessage && !((StreamedHttpMessage) message).getContent().isClosed()) {
        final Pipe<HttpContent> pipe = ((StreamedHttpMessage) message).getContent();

        ChannelPromise writeFuture = ctx.channel().newPromise();
        writeFuture.addListener(new ChannelFutureListener() {
            @Override//from w  w w  .  jav  a  2s  .c  om
            public void operationComplete(ChannelFuture future) throws Exception {
                // Channel's thread
                // First frame has been written

                if (future.isSuccess()) {
                    pipe.receive().addListener(new ChunkListener(ctx, streamId, pipe, promise));
                } else if (future.isCancelled()) {
                    pipe.close();
                    promise.cancel(true);
                } else {
                    pipe.close();
                    promise.setFailure(future.cause());
                }
            }
        });

        return writeFuture;
    } else {
        return promise;
    }
}

From source file:com.twitter.http2.HttpStreamEncoder.java

License:Apache License

private static ChannelPromise getFrameFuture(ChannelHandlerContext ctx, ChannelPromise future,
        HttpFrame[] httpFrames) {/*from  w ww  .  j  a  va2s  .c  o m*/
    ChannelPromise frameFuture = future;
    for (int i = httpFrames.length; --i >= 0;) {
        future = ctx.channel().newPromise();
        future.addListener(new HttpFrameWriter(ctx, frameFuture, httpFrames[i]));
        frameFuture = future;
    }
    return frameFuture;
}

From source file:com.vmware.dcp.common.http.netty.NettyWebSocketRequestHandler.java

License:Open Source License

private void performWebsocketHandshake(final ChannelHandlerContext ctx, FullHttpRequest nettyRequest) {
    WebSocketServerHandshakerFactory factory = new WebSocketServerHandshakerFactory(this.handshakePath, null,
            false);/*from  www . j a  va 2s. c om*/
    this.handshaker = factory.newHandshaker(nettyRequest);
    if (this.handshaker == null) {
        WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
    } else {
        ChannelPromise promise = new DefaultChannelPromise(ctx.channel());
        promise.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (!future.isSuccess()) {
                    ctx.channel().close();
                }
                ctx.channel().closeFuture().addListener(f -> {
                    for (java.util.Map.Entry<URI, Set<String>> e : NettyWebSocketRequestHandler.this.serviceSubscriptions
                            .entrySet()) {
                        WebSocketService svc = NettyWebSocketRequestHandler.this.webSocketServices
                                .get(e.getKey());
                        if (svc != null) {
                            deleteServiceSubscriptions(svc);
                        }
                        NettyWebSocketRequestHandler.this.host.stopService(svc);
                    }
                });
            }
        });
        DefaultHttpHeaders responseHeaders = new DefaultHttpHeaders();
        this.handshaker.handshake(ctx.channel(), nettyRequest, responseHeaders, promise);
    }
}

From source file:com.vmware.xenon.common.http.netty.NettyChannelPool.java

License:Open Source License

/**
 * When using HTTP/2, we have to wait for the settings to be negotiated before we can send
 * data. We wait for a promise that comes from the HTTP client channel pipeline
 *//* w ww .  ja  va2  s  . c o m*/
private void waitForSettings(Channel ch, NettyChannelContext contextFinal, Operation request,
        NettyChannelGroup group) {
    ChannelPromise settingsPromise = ch.attr(NettyChannelContext.SETTINGS_PROMISE_KEY).get();
    settingsPromise.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {

            if (future.isSuccess()) {

                // retrieve pending operations
                List<Operation> pendingOps = new ArrayList<>();
                synchronized (group) {
                    contextFinal.setOpenInProgress(false);
                    contextFinal.setChannel(future.channel()).setOperation(request);
                    pendingOps.addAll(group.pendingRequests);
                    group.pendingRequests.clear();
                }

                sendAfterConnect(future.channel(), contextFinal, request, group);

                // trigger pending operations
                for (Operation pendingOp : pendingOps) {
                    pendingOp.setSocketContext(contextFinal);
                    pendingOp.complete();
                }

            } else {
                returnOrClose(contextFinal, true);
                fail(request, future.cause());
            }
        }
    });
}

From source file:com.vmware.xenon.common.http.netty.NettyWebSocketRequestHandler.java

License:Open Source License

private void performWebsocketHandshake(final ChannelHandlerContext ctx, FullHttpRequest nettyRequest) {
    WebSocketServerHandshakerFactory factory = new WebSocketServerHandshakerFactory(this.handshakePath, null,
            false);/*from w  w w .j a  v  a2 s  .  c o m*/
    this.handshaker = factory.newHandshaker(nettyRequest);
    if (this.handshaker == null) {
        WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
    } else {
        ChannelPromise promise = new DefaultChannelPromise(ctx.channel());
        promise.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (!future.isSuccess()) {
                    ctx.channel().close();
                }
                ctx.channel().closeFuture().addListener(f -> {
                    for (java.util.Map.Entry<URI, Set<String>> e : NettyWebSocketRequestHandler.this.serviceSubscriptions
                            .entrySet()) {
                        WebSocketService svc = NettyWebSocketRequestHandler.this.webSocketServices
                                .get(e.getKey());
                        if (svc != null) {
                            deleteServiceSubscriptions(svc);
                        }
                        NettyWebSocketRequestHandler.this.host.stopService(svc);
                    }
                });
            }
        });
        DefaultHttpHeaders responseHeaders = new DefaultHttpHeaders();
        CharSequence token = nettyRequest.headers().get(Operation.REQUEST_AUTH_TOKEN_HEADER, null);
        if (token == null) {
            String cookie = nettyRequest.headers().get(HttpHeaderNames.COOKIE);
            if (cookie != null) {
                token = CookieJar.decodeCookies(cookie).get(AuthenticationConstants.REQUEST_AUTH_TOKEN_COOKIE);
            }

        }
        this.authToken = token == null ? null : token.toString();
        this.handshaker.handshake(ctx.channel(), nettyRequest, responseHeaders, promise);
    }
}

From source file:de.saxsys.synchronizefx.netty.base.client.NetworkEventHandlerClient.java

License:Open Source License

@Override
public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise)
        throws Exception {
    promise.addListener(new GenericFutureListener<Future<? super Void>>() {
        @Override//  ww w. ja v  a 2 s  . co m
        public void operationComplete(final Future<? super Void> future) throws Exception {
            Throwable cause = future.cause();
            if (cause != null) {
                exceptionCaught(ctx, cause);
            }
        }
    });
    ctx.write(msg, promise);
}