Search in sources :

Example 1 with WebSocketBean

use of io.micronaut.websocket.context.WebSocketBean in project micronaut-core by micronaut-projects.

the class AbstractNettyWebSocketHandler method callOpenMethod.

/**
 * Calls the open method of the websocket bean.
 *
 * @param ctx THe handler context
 */
protected void callOpenMethod(ChannelHandlerContext ctx) {
    if (session == null) {
        return;
    }
    Optional<? extends MethodExecutionHandle<?, ?>> executionHandle = webSocketBean.openMethod();
    if (executionHandle.isPresent()) {
        MethodExecutionHandle<?, ?> openMethod = executionHandle.get();
        BoundExecutable boundExecutable = null;
        try {
            boundExecutable = bindMethod(originatingRequest, webSocketBinder, openMethod, Collections.emptyList());
        } catch (Throwable e) {
            if (LOG.isErrorEnabled()) {
                LOG.error("Error Binding method @OnOpen for WebSocket [" + webSocketBean + "]: " + e.getMessage(), e);
            }
            if (session.isOpen()) {
                session.close(CloseReason.INTERNAL_ERROR);
            }
        }
        if (boundExecutable != null) {
            try {
                BoundExecutable finalBoundExecutable = boundExecutable;
                Object result = invokeExecutable(finalBoundExecutable, openMethod);
                if (Publishers.isConvertibleToPublisher(result)) {
                    Flux<?> flowable = Flux.from(instrumentPublisher(ctx, result));
                    flowable.subscribe(o -> {
                    }, error -> {
                        if (LOG.isErrorEnabled()) {
                            LOG.error("Error Opening WebSocket [" + webSocketBean + "]: " + error.getMessage(), error);
                        }
                        if (session.isOpen()) {
                            session.close(CloseReason.INTERNAL_ERROR);
                        }
                    }, () -> {
                    });
                }
            } catch (Throwable e) {
                forwardErrorToUser(ctx, t -> {
                    if (LOG.isErrorEnabled()) {
                        LOG.error("Error Opening WebSocket [" + webSocketBean + "]: " + t.getMessage(), t);
                    }
                }, e);
                // since we failed to call onOpen, we should always close here
                if (session.isOpen()) {
                    session.close(CloseReason.INTERNAL_ERROR);
                }
            }
        }
    }
}
Also used : Publishers(io.micronaut.core.async.publisher.Publishers) ArgumentBinderRegistry(io.micronaut.core.bind.ArgumentBinderRegistry) LoggerFactory(org.slf4j.LoggerFactory) Internal(io.micronaut.core.annotation.Internal) UnsatisfiedArgumentException(io.micronaut.core.bind.exceptions.UnsatisfiedArgumentException) CloseReason(io.micronaut.websocket.CloseReason) MediaType(io.micronaut.http.MediaType) Map(java.util.Map) RequestBinderRegistry(io.micronaut.http.bind.RequestBinderRegistry) DefaultExecutableBinder(io.micronaut.core.bind.DefaultExecutableBinder) CodecException(io.micronaut.http.codec.CodecException) ContinuationWebSocketFrame(io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame) WebSocketState(io.micronaut.websocket.bind.WebSocketState) CompositeByteBuf(io.netty.buffer.CompositeByteBuf) List(java.util.List) Optional(java.util.Optional) NettyByteBufferFactory(io.micronaut.buffer.netty.NettyByteBufferFactory) WebSocketBean(io.micronaut.websocket.context.WebSocketBean) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) ExecutableMethod(io.micronaut.inject.ExecutableMethod) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) WebSocketVersion(io.netty.handler.codec.http.websocketx.WebSocketVersion) ExecutableBinder(io.micronaut.core.bind.ExecutableBinder) ByteBuf(io.netty.buffer.ByteBuf) PongWebSocketFrame(io.netty.handler.codec.http.websocketx.PongWebSocketFrame) Schedulers(reactor.core.scheduler.Schedulers) CloseWebSocketFrame(io.netty.handler.codec.http.websocketx.CloseWebSocketFrame) Argument(io.micronaut.core.type.Argument) HttpRequest(io.micronaut.http.HttpRequest) BoundExecutable(io.micronaut.core.bind.BoundExecutable) ConversionService(io.micronaut.core.convert.ConversionService) MediaTypeCodecRegistry(io.micronaut.http.codec.MediaTypeCodecRegistry) Logger(org.slf4j.Logger) WebSocketFrame(io.netty.handler.codec.http.websocketx.WebSocketFrame) PingWebSocketFrame(io.netty.handler.codec.http.websocketx.PingWebSocketFrame) Publisher(org.reactivestreams.Publisher) IOException(java.io.IOException) MethodExecutionHandle(io.micronaut.inject.MethodExecutionHandle) Channel(io.netty.channel.Channel) BinaryWebSocketFrame(io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame) Consumer(java.util.function.Consumer) Flux(reactor.core.publisher.Flux) WebSocketStateBinderRegistry(io.micronaut.websocket.bind.WebSocketStateBinderRegistry) TextWebSocketFrame(io.netty.handler.codec.http.websocketx.TextWebSocketFrame) SimpleChannelInboundHandler(io.netty.channel.SimpleChannelInboundHandler) Consumes(io.micronaut.http.annotation.Consumes) WebSocketPongMessage(io.micronaut.websocket.WebSocketPongMessage) Collections(java.util.Collections) BoundExecutable(io.micronaut.core.bind.BoundExecutable)

Example 2 with WebSocketBean

use of io.micronaut.websocket.context.WebSocketBean in project micronaut-core by micronaut-projects.

the class NettyServerWebSocketUpgradeHandler method handleHandshake.

/**
 * Do the handshaking for WebSocket request.
 *
 * @param ctx           The channel handler context
 * @param req           The request
 * @param webSocketBean The web socket bean
 * @param response      The response
 * @return The channel future
 */
protected ChannelFuture handleHandshake(ChannelHandlerContext ctx, NettyHttpRequest req, WebSocketBean<?> webSocketBean, MutableHttpResponse<?> response) {
    int maxFramePayloadLength = webSocketBean.messageMethod().map(m -> m.intValue(OnMessage.class, "maxPayloadLength").orElse(65536)).orElse(65536);
    String subprotocols = webSocketBean.getBeanDefinition().stringValue(ServerWebSocket.class, "subprotocols").filter(s -> !StringUtils.isEmpty(s)).orElse(null);
    WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketURL(ctx, req), subprotocols, true, maxFramePayloadLength);
    handshaker = wsFactory.newHandshaker(req.getNativeRequest());
    MutableHttpHeaders headers = response.getHeaders();
    io.netty.handler.codec.http.HttpHeaders nettyHeaders;
    if (headers instanceof NettyHttpHeaders) {
        nettyHeaders = ((NettyHttpHeaders) headers).getNettyHeaders();
    } else {
        nettyHeaders = new DefaultHttpHeaders();
        for (Map.Entry<String, List<String>> entry : headers) {
            nettyHeaders.add(entry.getKey(), entry.getValue());
        }
    }
    Channel channel = ctx.channel();
    if (handshaker == null) {
        return WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(channel);
    } else {
        return handshaker.handshake(channel, req.getNativeRequest(), nettyHeaders, channel.newPromise());
    }
}
Also used : RouteExecutor(io.micronaut.http.server.RouteExecutor) HttpHeaders(io.netty.handler.codec.http.HttpHeaders) WebSocketServerHandshakerFactory(io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory) LoggerFactory(org.slf4j.LoggerFactory) AsciiString(io.netty.util.AsciiString) Internal(io.micronaut.core.annotation.Internal) CloseReason(io.micronaut.websocket.CloseReason) OnOpen(io.micronaut.websocket.annotation.OnOpen) HttpStatus(io.micronaut.http.HttpStatus) Map(java.util.Map) HttpResponse(io.micronaut.http.HttpResponse) RequestBinderRegistry(io.micronaut.http.bind.RequestBinderRegistry) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) MutableHttpHeaders(io.micronaut.http.MutableHttpHeaders) ChannelPipeline(io.netty.channel.ChannelPipeline) StringUtils(io.micronaut.core.util.StringUtils) List(java.util.List) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) SslHandler(io.netty.handler.ssl.SslHandler) Optional(java.util.Optional) HttpAttributes(io.micronaut.http.HttpAttributes) WebSocketSessionRepository(io.micronaut.http.netty.websocket.WebSocketSessionRepository) WebSocketBean(io.micronaut.websocket.context.WebSocketBean) OnMessage(io.micronaut.websocket.annotation.OnMessage) Scheduler(reactor.core.scheduler.Scheduler) AtomicReference(java.util.concurrent.atomic.AtomicReference) WebSocketBeanRegistry(io.micronaut.websocket.context.WebSocketBeanRegistry) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) NettyHttpHeaders(io.micronaut.http.netty.NettyHttpHeaders) UriRouteMatch(io.micronaut.web.router.UriRouteMatch) Schedulers(reactor.core.scheduler.Schedulers) CloseWebSocketFrame(io.netty.handler.codec.http.websocketx.CloseWebSocketFrame) HttpRequest(io.micronaut.http.HttpRequest) ServerRequestContext(io.micronaut.http.context.ServerRequestContext) MediaTypeCodecRegistry(io.micronaut.http.codec.MediaTypeCodecRegistry) HttpStatusException(io.micronaut.http.exceptions.HttpStatusException) HttpMethod(io.micronaut.http.HttpMethod) Logger(org.slf4j.Logger) HttpHeaderValues(io.netty.handler.codec.http.HttpHeaderValues) Publisher(org.reactivestreams.Publisher) Mono(reactor.core.publisher.Mono) ChannelFuture(io.netty.channel.ChannelFuture) Channel(io.netty.channel.Channel) Consumer(java.util.function.Consumer) NonNull(io.micronaut.core.annotation.NonNull) Flux(reactor.core.publisher.Flux) NettyEmbeddedServices(io.micronaut.http.server.netty.NettyEmbeddedServices) SimpleChannelInboundHandler(io.netty.channel.SimpleChannelInboundHandler) ServerWebSocket(io.micronaut.websocket.annotation.ServerWebSocket) WebSocketServerHandshaker(io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker) ChannelPipelineCustomizer(io.micronaut.http.netty.channel.ChannelPipelineCustomizer) ChannelHandler(io.netty.channel.ChannelHandler) HttpHeaderNames(io.netty.handler.codec.http.HttpHeaderNames) Router(io.micronaut.web.router.Router) HttpHeaders(io.netty.handler.codec.http.HttpHeaders) Channel(io.netty.channel.Channel) WebSocketServerHandshakerFactory(io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory) OnMessage(io.micronaut.websocket.annotation.OnMessage) AsciiString(io.netty.util.AsciiString) NettyHttpHeaders(io.micronaut.http.netty.NettyHttpHeaders) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) MutableHttpHeaders(io.micronaut.http.MutableHttpHeaders) List(java.util.List) Map(java.util.Map)

Example 3 with WebSocketBean

use of io.micronaut.websocket.context.WebSocketBean in project micronaut-core by micronaut-projects.

the class NettyServerWebSocketUpgradeHandler method channelRead0.

@Override
protected final void channelRead0(ChannelHandlerContext ctx, NettyHttpRequest<?> msg) {
    ServerRequestContext.set(msg);
    Optional<UriRouteMatch<Object, Object>> optionalRoute = router.find(HttpMethod.GET, msg.getUri().toString(), msg).filter(rm -> rm.isAnnotationPresent(OnMessage.class) || rm.isAnnotationPresent(OnOpen.class)).findFirst();
    MutableHttpResponse<?> proceed = HttpResponse.ok();
    AtomicReference<HttpRequest<?>> requestReference = new AtomicReference<>(msg);
    Flux<MutableHttpResponse<?>> responsePublisher;
    if (optionalRoute.isPresent()) {
        UriRouteMatch<Object, Object> rm = optionalRoute.get();
        msg.setAttribute(HttpAttributes.ROUTE_MATCH, rm);
        msg.setAttribute(HttpAttributes.ROUTE_INFO, rm);
        proceed.setAttribute(HttpAttributes.ROUTE_MATCH, rm);
        proceed.setAttribute(HttpAttributes.ROUTE_INFO, rm);
        responsePublisher = Flux.just(proceed);
    } else {
        responsePublisher = routeExecutor.onError(new HttpStatusException(HttpStatus.NOT_FOUND, "WebSocket Not Found"), msg);
    }
    Publisher<? extends MutableHttpResponse<?>> finalPublisher = routeExecutor.filterPublisher(requestReference, responsePublisher);
    final Scheduler scheduler = Schedulers.fromExecutorService(ctx.channel().eventLoop());
    Mono.from(finalPublisher).publishOn(scheduler).subscribeOn(scheduler).contextWrite(reactorContext -> reactorContext.put(ServerRequestContext.KEY, requestReference.get())).subscribe((Consumer<MutableHttpResponse<?>>) actualResponse -> {
        if (actualResponse == proceed) {
            UriRouteMatch routeMatch = actualResponse.getAttribute(HttpAttributes.ROUTE_MATCH, UriRouteMatch.class).get();
            WebSocketBean<?> webSocketBean = webSocketBeanRegistry.getWebSocket(routeMatch.getTarget().getClass());
            handleHandshake(ctx, msg, webSocketBean, actualResponse);
            ChannelPipeline pipeline = ctx.pipeline();
            try {
                NettyServerWebSocketHandler webSocketHandler = new NettyServerWebSocketHandler(nettyEmbeddedServices, webSocketSessionRepository, handshaker, webSocketBean, msg, routeMatch, ctx, routeExecutor.getCoroutineHelper().orElse(null));
                pipeline.addBefore(ctx.name(), NettyServerWebSocketHandler.ID, webSocketHandler);
                pipeline.remove(ChannelPipelineCustomizer.HANDLER_HTTP_STREAM);
                pipeline.remove(NettyServerWebSocketUpgradeHandler.this);
                ChannelHandler accessLoggerHandler = pipeline.get(ChannelPipelineCustomizer.HANDLER_ACCESS_LOGGER);
                if (accessLoggerHandler != null) {
                    pipeline.remove(accessLoggerHandler);
                }
            } catch (Throwable e) {
                if (LOG.isErrorEnabled()) {
                    LOG.error("Error opening WebSocket: " + e.getMessage(), e);
                }
                ctx.writeAndFlush(new CloseWebSocketFrame(CloseReason.INTERNAL_ERROR.getCode(), CloseReason.INTERNAL_ERROR.getReason()));
            }
        } else {
            ctx.writeAndFlush(actualResponse);
        }
    });
}
Also used : RouteExecutor(io.micronaut.http.server.RouteExecutor) HttpHeaders(io.netty.handler.codec.http.HttpHeaders) WebSocketServerHandshakerFactory(io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory) LoggerFactory(org.slf4j.LoggerFactory) AsciiString(io.netty.util.AsciiString) Internal(io.micronaut.core.annotation.Internal) CloseReason(io.micronaut.websocket.CloseReason) OnOpen(io.micronaut.websocket.annotation.OnOpen) HttpStatus(io.micronaut.http.HttpStatus) Map(java.util.Map) HttpResponse(io.micronaut.http.HttpResponse) RequestBinderRegistry(io.micronaut.http.bind.RequestBinderRegistry) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) MutableHttpHeaders(io.micronaut.http.MutableHttpHeaders) ChannelPipeline(io.netty.channel.ChannelPipeline) StringUtils(io.micronaut.core.util.StringUtils) List(java.util.List) DefaultHttpHeaders(io.netty.handler.codec.http.DefaultHttpHeaders) SslHandler(io.netty.handler.ssl.SslHandler) Optional(java.util.Optional) HttpAttributes(io.micronaut.http.HttpAttributes) WebSocketSessionRepository(io.micronaut.http.netty.websocket.WebSocketSessionRepository) WebSocketBean(io.micronaut.websocket.context.WebSocketBean) OnMessage(io.micronaut.websocket.annotation.OnMessage) Scheduler(reactor.core.scheduler.Scheduler) AtomicReference(java.util.concurrent.atomic.AtomicReference) WebSocketBeanRegistry(io.micronaut.websocket.context.WebSocketBeanRegistry) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) NettyHttpHeaders(io.micronaut.http.netty.NettyHttpHeaders) UriRouteMatch(io.micronaut.web.router.UriRouteMatch) Schedulers(reactor.core.scheduler.Schedulers) CloseWebSocketFrame(io.netty.handler.codec.http.websocketx.CloseWebSocketFrame) HttpRequest(io.micronaut.http.HttpRequest) ServerRequestContext(io.micronaut.http.context.ServerRequestContext) MediaTypeCodecRegistry(io.micronaut.http.codec.MediaTypeCodecRegistry) HttpStatusException(io.micronaut.http.exceptions.HttpStatusException) HttpMethod(io.micronaut.http.HttpMethod) Logger(org.slf4j.Logger) HttpHeaderValues(io.netty.handler.codec.http.HttpHeaderValues) Publisher(org.reactivestreams.Publisher) Mono(reactor.core.publisher.Mono) ChannelFuture(io.netty.channel.ChannelFuture) Channel(io.netty.channel.Channel) Consumer(java.util.function.Consumer) NonNull(io.micronaut.core.annotation.NonNull) Flux(reactor.core.publisher.Flux) NettyEmbeddedServices(io.micronaut.http.server.netty.NettyEmbeddedServices) SimpleChannelInboundHandler(io.netty.channel.SimpleChannelInboundHandler) ServerWebSocket(io.micronaut.websocket.annotation.ServerWebSocket) WebSocketServerHandshaker(io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker) ChannelPipelineCustomizer(io.micronaut.http.netty.channel.ChannelPipelineCustomizer) ChannelHandler(io.netty.channel.ChannelHandler) HttpHeaderNames(io.netty.handler.codec.http.HttpHeaderNames) Router(io.micronaut.web.router.Router) NettyHttpRequest(io.micronaut.http.server.netty.NettyHttpRequest) HttpRequest(io.micronaut.http.HttpRequest) CloseWebSocketFrame(io.netty.handler.codec.http.websocketx.CloseWebSocketFrame) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) Scheduler(reactor.core.scheduler.Scheduler) WebSocketBean(io.micronaut.websocket.context.WebSocketBean) HttpStatusException(io.micronaut.http.exceptions.HttpStatusException) AtomicReference(java.util.concurrent.atomic.AtomicReference) OnMessage(io.micronaut.websocket.annotation.OnMessage) OnOpen(io.micronaut.websocket.annotation.OnOpen) ChannelHandler(io.netty.channel.ChannelHandler) ChannelPipeline(io.netty.channel.ChannelPipeline) UriRouteMatch(io.micronaut.web.router.UriRouteMatch)

Example 4 with WebSocketBean

use of io.micronaut.websocket.context.WebSocketBean in project micronaut-core by micronaut-projects.

the class AbstractNettyWebSocketHandler method handleWebSocketFrame.

/**
 * Handles WebSocket frame request.
 *
 * @param ctx The context
 * @param msg The frame
 */
protected void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame msg) {
    if (msg instanceof TextWebSocketFrame || msg instanceof BinaryWebSocketFrame || msg instanceof ContinuationWebSocketFrame) {
        if (messageHandler == null) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("WebSocket bean [" + webSocketBean.getTarget() + "] received message, but defined no @OnMessage handler. Dropping frame...");
            }
            writeCloseFrameAndTerminate(ctx, CloseReason.UNSUPPORTED_DATA);
        } else {
            ByteBuf msgContent = msg.content().retain();
            if (!msg.isFinalFragment()) {
                frameBuffer.updateAndGet((buffer) -> {
                    if (buffer == null) {
                        buffer = ctx.alloc().compositeBuffer();
                    }
                    buffer.addComponent(true, msgContent);
                    return buffer;
                });
                return;
            }
            ByteBuf content;
            CompositeByteBuf buffer = frameBuffer.getAndSet(null);
            if (buffer == null) {
                content = msgContent;
            } else {
                buffer.addComponent(true, msgContent);
                content = buffer;
            }
            Argument<?> bodyArgument = this.getBodyArgument();
            Optional<?> converted = ConversionService.SHARED.convert(content, bodyArgument);
            content.release();
            if (!converted.isPresent()) {
                MediaType mediaType;
                try {
                    mediaType = messageHandler.stringValue(Consumes.class).map(MediaType::of).orElse(MediaType.APPLICATION_JSON_TYPE);
                } catch (IllegalArgumentException e) {
                    exceptionCaught(ctx, e);
                    return;
                }
                try {
                    converted = mediaTypeCodecRegistry.findCodec(mediaType).map(codec -> codec.decode(bodyArgument, new NettyByteBufferFactory(ctx.alloc()).wrap(msg.content())));
                } catch (CodecException e) {
                    messageProcessingException(ctx, e);
                    return;
                }
            }
            if (converted.isPresent()) {
                Object v = converted.get();
                NettyWebSocketSession currentSession = getSession();
                ExecutableBinder<WebSocketState> executableBinder = new DefaultExecutableBinder<>(Collections.singletonMap(bodyArgument, v));
                try {
                    BoundExecutable boundExecutable = executableBinder.bind(messageHandler.getExecutableMethod(), webSocketBinder, new WebSocketState(currentSession, originatingRequest));
                    Object result = invokeExecutable(boundExecutable, messageHandler);
                    if (Publishers.isConvertibleToPublisher(result)) {
                        Flux<?> flowable = Flux.from(instrumentPublisher(ctx, result));
                        flowable.subscribe(o -> {
                        }, error -> messageProcessingException(ctx, error), () -> messageHandled(ctx, session, v));
                    } else {
                        messageHandled(ctx, session, v);
                    }
                } catch (Throwable e) {
                    messageProcessingException(ctx, e);
                }
            } else {
                writeCloseFrameAndTerminate(ctx, CloseReason.UNSUPPORTED_DATA.getCode(), CloseReason.UNSUPPORTED_DATA.getReason() + ": " + "Received data cannot be converted to target type: " + bodyArgument);
            }
        }
    } else if (msg instanceof PingWebSocketFrame) {
        // respond with pong
        PingWebSocketFrame frame = (PingWebSocketFrame) msg.retain();
        ctx.writeAndFlush(new PongWebSocketFrame(frame.content()));
    } else if (msg instanceof PongWebSocketFrame) {
        if (pongHandler != null) {
            ByteBuf content = msg.content();
            WebSocketPongMessage message = new WebSocketPongMessage(NettyByteBufferFactory.DEFAULT.wrap(content));
            NettyWebSocketSession currentSession = getSession();
            ExecutableBinder<WebSocketState> executableBinder = new DefaultExecutableBinder<>(Collections.singletonMap(getPongArgument(), message));
            try {
                BoundExecutable boundExecutable = executableBinder.bind(pongHandler.getExecutableMethod(), webSocketBinder, new WebSocketState(currentSession, originatingRequest));
                Object result = invokeExecutable(boundExecutable, pongHandler);
                if (Publishers.isConvertibleToPublisher(result)) {
                    // delay the buffer release until the publisher has completed
                    content.retain();
                    Flux<?> flowable = Flux.from(instrumentPublisher(ctx, result));
                    flowable.subscribe(o -> {
                    }, error -> {
                        if (LOG.isErrorEnabled()) {
                            LOG.error("Error Processing WebSocket Pong Message [" + webSocketBean + "]: " + error.getMessage(), error);
                        }
                        exceptionCaught(ctx, error);
                    }, content::release);
                }
            } catch (Throwable e) {
                if (LOG.isErrorEnabled()) {
                    LOG.error("Error Processing WebSocket Message [" + webSocketBean + "]: " + e.getMessage(), e);
                }
                exceptionCaught(ctx, e);
            }
        }
    } else if (msg instanceof CloseWebSocketFrame) {
        CloseWebSocketFrame cwsf = (CloseWebSocketFrame) msg;
        handleCloseFrame(ctx, cwsf);
    } else {
        writeCloseFrameAndTerminate(ctx, CloseReason.UNSUPPORTED_DATA);
    }
}
Also used : Publishers(io.micronaut.core.async.publisher.Publishers) ArgumentBinderRegistry(io.micronaut.core.bind.ArgumentBinderRegistry) LoggerFactory(org.slf4j.LoggerFactory) Internal(io.micronaut.core.annotation.Internal) UnsatisfiedArgumentException(io.micronaut.core.bind.exceptions.UnsatisfiedArgumentException) CloseReason(io.micronaut.websocket.CloseReason) MediaType(io.micronaut.http.MediaType) Map(java.util.Map) RequestBinderRegistry(io.micronaut.http.bind.RequestBinderRegistry) DefaultExecutableBinder(io.micronaut.core.bind.DefaultExecutableBinder) CodecException(io.micronaut.http.codec.CodecException) ContinuationWebSocketFrame(io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame) WebSocketState(io.micronaut.websocket.bind.WebSocketState) CompositeByteBuf(io.netty.buffer.CompositeByteBuf) List(java.util.List) Optional(java.util.Optional) NettyByteBufferFactory(io.micronaut.buffer.netty.NettyByteBufferFactory) WebSocketBean(io.micronaut.websocket.context.WebSocketBean) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) ExecutableMethod(io.micronaut.inject.ExecutableMethod) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) WebSocketVersion(io.netty.handler.codec.http.websocketx.WebSocketVersion) ExecutableBinder(io.micronaut.core.bind.ExecutableBinder) ByteBuf(io.netty.buffer.ByteBuf) PongWebSocketFrame(io.netty.handler.codec.http.websocketx.PongWebSocketFrame) Schedulers(reactor.core.scheduler.Schedulers) CloseWebSocketFrame(io.netty.handler.codec.http.websocketx.CloseWebSocketFrame) Argument(io.micronaut.core.type.Argument) HttpRequest(io.micronaut.http.HttpRequest) BoundExecutable(io.micronaut.core.bind.BoundExecutable) ConversionService(io.micronaut.core.convert.ConversionService) MediaTypeCodecRegistry(io.micronaut.http.codec.MediaTypeCodecRegistry) Logger(org.slf4j.Logger) WebSocketFrame(io.netty.handler.codec.http.websocketx.WebSocketFrame) PingWebSocketFrame(io.netty.handler.codec.http.websocketx.PingWebSocketFrame) Publisher(org.reactivestreams.Publisher) IOException(java.io.IOException) MethodExecutionHandle(io.micronaut.inject.MethodExecutionHandle) Channel(io.netty.channel.Channel) BinaryWebSocketFrame(io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame) Consumer(java.util.function.Consumer) Flux(reactor.core.publisher.Flux) WebSocketStateBinderRegistry(io.micronaut.websocket.bind.WebSocketStateBinderRegistry) TextWebSocketFrame(io.netty.handler.codec.http.websocketx.TextWebSocketFrame) SimpleChannelInboundHandler(io.netty.channel.SimpleChannelInboundHandler) Consumes(io.micronaut.http.annotation.Consumes) WebSocketPongMessage(io.micronaut.websocket.WebSocketPongMessage) Collections(java.util.Collections) BinaryWebSocketFrame(io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame) CompositeByteBuf(io.netty.buffer.CompositeByteBuf) ByteBuf(io.netty.buffer.ByteBuf) PingWebSocketFrame(io.netty.handler.codec.http.websocketx.PingWebSocketFrame) CompositeByteBuf(io.netty.buffer.CompositeByteBuf) PongWebSocketFrame(io.netty.handler.codec.http.websocketx.PongWebSocketFrame) Consumes(io.micronaut.http.annotation.Consumes) TextWebSocketFrame(io.netty.handler.codec.http.websocketx.TextWebSocketFrame) MediaType(io.micronaut.http.MediaType) CodecException(io.micronaut.http.codec.CodecException) CloseWebSocketFrame(io.netty.handler.codec.http.websocketx.CloseWebSocketFrame) NettyByteBufferFactory(io.micronaut.buffer.netty.NettyByteBufferFactory) ContinuationWebSocketFrame(io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame) DefaultExecutableBinder(io.micronaut.core.bind.DefaultExecutableBinder) BoundExecutable(io.micronaut.core.bind.BoundExecutable) WebSocketPongMessage(io.micronaut.websocket.WebSocketPongMessage) WebSocketState(io.micronaut.websocket.bind.WebSocketState)

Example 5 with WebSocketBean

use of io.micronaut.websocket.context.WebSocketBean in project micronaut-core by micronaut-projects.

the class DefaultHttpClient method connectWebSocket.

private <T> Flux<T> connectWebSocket(URI uri, MutableHttpRequest<?> request, Class<T> clientEndpointType, WebSocketBean<T> webSocketBean) {
    Bootstrap bootstrap = this.bootstrap.clone();
    if (webSocketBean == null) {
        webSocketBean = webSocketRegistry.getWebSocket(clientEndpointType);
    }
    WebSocketBean<T> finalWebSocketBean = webSocketBean;
    return Flux.create(emitter -> {
        SslContext sslContext = buildSslContext(uri);
        WebSocketVersion protocolVersion = finalWebSocketBean.getBeanDefinition().enumValue(ClientWebSocket.class, "version", WebSocketVersion.class).orElse(WebSocketVersion.V13);
        int maxFramePayloadLength = finalWebSocketBean.messageMethod().map(m -> m.intValue(OnMessage.class, "maxPayloadLength").orElse(65536)).orElse(65536);
        String subprotocol = finalWebSocketBean.getBeanDefinition().stringValue(ClientWebSocket.class, "subprotocol").orElse(StringUtils.EMPTY_STRING);
        RequestKey requestKey;
        try {
            requestKey = new RequestKey(uri);
        } catch (HttpClientException e) {
            emitter.error(e);
            return;
        }
        bootstrap.remoteAddress(requestKey.getHost(), requestKey.getPort());
        initBootstrapForProxy(bootstrap, sslContext != null, requestKey.getHost(), requestKey.getPort());
        bootstrap.handler(new HttpClientInitializer(sslContext, requestKey.getHost(), requestKey.getPort(), false, false, false, null) {

            @Override
            protected void addFinalHandler(ChannelPipeline pipeline) {
                pipeline.remove(ChannelPipelineCustomizer.HANDLER_HTTP_DECODER);
                ReadTimeoutHandler readTimeoutHandler = pipeline.get(ReadTimeoutHandler.class);
                if (readTimeoutHandler != null) {
                    pipeline.remove(readTimeoutHandler);
                }
                Optional<Duration> readIdleTime = configuration.getReadIdleTimeout();
                if (readIdleTime.isPresent()) {
                    Duration duration = readIdleTime.get();
                    if (!duration.isNegative()) {
                        pipeline.addLast(ChannelPipelineCustomizer.HANDLER_IDLE_STATE, new IdleStateHandler(duration.toMillis(), duration.toMillis(), duration.toMillis(), TimeUnit.MILLISECONDS));
                    }
                }
                final NettyWebSocketClientHandler webSocketHandler;
                try {
                    String scheme = (sslContext == null) ? "ws" : "wss";
                    URI webSocketURL = UriBuilder.of(uri).scheme(scheme).host(host).port(port).build();
                    MutableHttpHeaders headers = request.getHeaders();
                    HttpHeaders customHeaders = EmptyHttpHeaders.INSTANCE;
                    if (headers instanceof NettyHttpHeaders) {
                        customHeaders = ((NettyHttpHeaders) headers).getNettyHeaders();
                    }
                    if (StringUtils.isNotEmpty(subprotocol)) {
                        customHeaders.add("Sec-WebSocket-Protocol", subprotocol);
                    }
                    webSocketHandler = new NettyWebSocketClientHandler<>(request, finalWebSocketBean, WebSocketClientHandshakerFactory.newHandshaker(webSocketURL, protocolVersion, subprotocol, true, customHeaders, maxFramePayloadLength), requestBinderRegistry, mediaTypeCodecRegistry, emitter);
                    pipeline.addLast(WebSocketClientCompressionHandler.INSTANCE);
                    pipeline.addLast(ChannelPipelineCustomizer.HANDLER_MICRONAUT_WEBSOCKET_CLIENT, webSocketHandler);
                } catch (Throwable e) {
                    emitter.error(new WebSocketSessionException("Error opening WebSocket client session: " + e.getMessage(), e));
                }
            }
        });
        addInstrumentedListener(bootstrap.connect(), future -> {
            if (!future.isSuccess()) {
                emitter.error(future.cause());
            }
        });
    }, FluxSink.OverflowStrategy.ERROR);
}
Also used : AttributeKey(io.netty.util.AttributeKey) OrderUtil(io.micronaut.core.order.OrderUtil) Publishers(io.micronaut.core.async.publisher.Publishers) NoHostException(io.micronaut.http.client.exceptions.NoHostException) Processor(org.reactivestreams.Processor) JacksonDatabindMapper(io.micronaut.jackson.databind.JacksonDatabindMapper) ProxyHttpClient(io.micronaut.http.client.ProxyHttpClient) HttpProxyHandler(io.netty.handler.proxy.HttpProxyHandler) SseClient(io.micronaut.http.client.sse.SseClient) ChunkedWriteHandler(io.netty.handler.stream.ChunkedWriteHandler) HANDLER_IDLE_STATE(io.micronaut.http.netty.channel.ChannelPipelineCustomizer.HANDLER_IDLE_STATE) Internal(io.micronaut.core.annotation.Internal) NettyClientSslBuilder(io.micronaut.http.client.netty.ssl.NettyClientSslBuilder) Proxy(java.net.Proxy) InstantiationUtils(io.micronaut.core.reflect.InstantiationUtils) HttpStatus(io.micronaut.http.HttpStatus) Duration(java.time.Duration) CharsetUtil(io.netty.util.CharsetUtil) HANDLER_HTTP2_SETTINGS(io.micronaut.http.netty.channel.ChannelPipelineCustomizer.HANDLER_HTTP2_SETTINGS) HttpClientResponseException(io.micronaut.http.client.exceptions.HttpClientResponseException) ArgumentUtils(io.micronaut.core.util.ArgumentUtils) WebSocketClientHandshakerFactory(io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory) MapperMediaTypeCodec(io.micronaut.json.codec.MapperMediaTypeCodec) LoadBalancer(io.micronaut.http.client.LoadBalancer) SocketChannel(io.netty.channel.socket.SocketChannel) HttpClientErrorDecoder(io.micronaut.http.client.exceptions.HttpClientErrorDecoder) ResourceResolver(io.micronaut.core.io.ResourceResolver) ByteBufferFactory(io.micronaut.core.io.buffer.ByteBufferFactory) ReadTimeoutException(io.micronaut.http.client.exceptions.ReadTimeoutException) IdleStateEvent(io.netty.handler.timeout.IdleStateEvent) ChannelHealthChecker(io.netty.channel.pool.ChannelHealthChecker) StreamingInboundHttp2ToHttpAdapter(io.micronaut.http.netty.stream.StreamingInboundHttp2ToHttpAdapter) StandardCharsets(java.nio.charset.StandardCharsets) HttpFilterResolver(io.micronaut.http.filter.HttpFilterResolver) ClientFilterResolutionContext(io.micronaut.http.client.filter.ClientFilterResolutionContext) LineBasedFrameDecoder(io.netty.handler.codec.LineBasedFrameDecoder) AbstractChannelPoolHandler(io.netty.channel.pool.AbstractChannelPoolHandler) SslHandler(io.netty.handler.ssl.SslHandler) ReferenceCountUtil(io.netty.util.ReferenceCountUtil) MutableHttpRequest(io.micronaut.http.MutableHttpRequest) NettyWebSocketClientHandler(io.micronaut.http.client.netty.websocket.NettyWebSocketClientHandler) ChannelPoolMap(io.netty.channel.pool.ChannelPoolMap) MultipartDataFactory(io.micronaut.http.client.multipart.MultipartDataFactory) NettyByteBufferFactory(io.micronaut.buffer.netty.NettyByteBufferFactory) java.util(java.util) Disposable(reactor.core.Disposable) WebSocketBean(io.micronaut.websocket.context.WebSocketBean) OnMessage(io.micronaut.websocket.annotation.OnMessage) ContentLengthExceededException(io.micronaut.http.client.exceptions.ContentLengthExceededException) Supplier(java.util.function.Supplier) StreamedHttpResponse(io.micronaut.http.netty.stream.StreamedHttpResponse) NettyThreadFactory(io.micronaut.http.netty.channel.NettyThreadFactory) NettyHttpRequestBuilder(io.micronaut.http.netty.NettyHttpRequestBuilder) DefaultHttpClientConfiguration(io.micronaut.http.client.DefaultHttpClientConfiguration) NettyHttpHeaders(io.micronaut.http.netty.NettyHttpHeaders) Nullable(io.micronaut.core.annotation.Nullable) ByteBuffer(io.micronaut.core.io.buffer.ByteBuffer) JsonStreamMediaTypeCodec(io.micronaut.json.codec.JsonStreamMediaTypeCodec) Argument(io.micronaut.core.type.Argument) MultipartException(io.micronaut.http.multipart.MultipartException) ConversionService(io.micronaut.core.convert.ConversionService) ServerRequestContext(io.micronaut.http.context.ServerRequestContext) NOOP(io.micronaut.scheduling.instrument.InvocationInstrumenter.NOOP) MediaTypeCodecRegistry(io.micronaut.http.codec.MediaTypeCodecRegistry) Attribute(io.netty.util.Attribute) JsonNode(io.micronaut.json.tree.JsonNode) SslContext(io.netty.handler.ssl.SslContext) FileUpload(io.netty.handler.codec.http.multipart.FileUpload) Publisher(org.reactivestreams.Publisher) HttpClientConfiguration(io.micronaut.http.client.HttpClientConfiguration) Mono(reactor.core.publisher.Mono) IOException(java.io.IOException) NettyHttpResponseBuilder(io.micronaut.http.netty.NettyHttpResponseBuilder) File(java.io.File) AbstractNettyHttpRequest(io.micronaut.http.netty.AbstractNettyHttpRequest) SimpleChannelPool(io.netty.channel.pool.SimpleChannelPool) Bootstrap(io.netty.bootstrap.Bootstrap) Flux(reactor.core.publisher.Flux) WebSocketClientCompressionHandler(io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketClientCompressionHandler) DEFAULT_SHUTDOWN_TIMEOUT_MILLISECONDS(io.micronaut.http.client.HttpClientConfiguration.DEFAULT_SHUTDOWN_TIMEOUT_MILLISECONDS) ChannelPipelineCustomizer(io.micronaut.http.netty.channel.ChannelPipelineCustomizer) ChannelPool(io.netty.channel.pool.ChannelPool) Instrumentation(io.micronaut.scheduling.instrument.Instrumentation) WebSocketClient(io.micronaut.websocket.WebSocketClient) Future(io.netty.util.concurrent.Future) DefaultThreadFactory(io.netty.util.concurrent.DefaultThreadFactory) ChannelPipelineListener(io.micronaut.http.netty.channel.ChannelPipelineListener) DefaultStreamedHttpResponse(io.micronaut.http.netty.stream.DefaultStreamedHttpResponse) SocketAddress(java.net.SocketAddress) HttpStreamsClientHandler(io.micronaut.http.netty.stream.HttpStreamsClientHandler) UriTemplate(io.micronaut.http.uri.UriTemplate) io.netty.handler.codec.http2(io.netty.handler.codec.http2) ByteBufAllocator(io.netty.buffer.ByteBufAllocator) URISyntaxException(java.net.URISyntaxException) DEFAULT_SHUTDOWN_QUIET_PERIOD_MILLISECONDS(io.micronaut.http.client.HttpClientConfiguration.DEFAULT_SHUTDOWN_QUIET_PERIOD_MILLISECONDS) ArrayUtils(io.micronaut.core.util.ArrayUtils) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) InvocationInstrumenter(io.micronaut.scheduling.instrument.InvocationInstrumenter) InvocationInstrumenterFactory(io.micronaut.scheduling.instrument.InvocationInstrumenterFactory) ClientFilterChain(io.micronaut.http.filter.ClientFilterChain) DefaultHttp2Content(io.micronaut.http.netty.stream.DefaultHttp2Content) Event(io.micronaut.http.sse.Event) Unpooled(io.netty.buffer.Unpooled) FixedChannelPool(io.netty.channel.pool.FixedChannelPool) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) MediaType(io.micronaut.http.MediaType) ReferenceCounted(io.micronaut.core.io.buffer.ReferenceCounted) JsonMapper(io.micronaut.json.JsonMapper) ApplicationProtocolNegotiationHandler(io.netty.handler.ssl.ApplicationProtocolNegotiationHandler) HttpResponse(io.micronaut.http.HttpResponse) ApplicationConfiguration(io.micronaut.runtime.ApplicationConfiguration) URI(java.net.URI) HttpClient(io.micronaut.http.client.HttpClient) HttpDataFactory(io.netty.handler.codec.http.multipart.HttpDataFactory) ThreadFactory(java.util.concurrent.ThreadFactory) RequestBinderRegistry(io.micronaut.http.bind.RequestBinderRegistry) MultipartBody(io.micronaut.http.client.multipart.MultipartBody) JsonMediaTypeCodec(io.micronaut.json.codec.JsonMediaTypeCodec) CodecException(io.micronaut.http.codec.CodecException) ReadTimeoutHandler(io.netty.handler.timeout.ReadTimeoutHandler) MutableHttpResponse(io.micronaut.http.MutableHttpResponse) MutableHttpHeaders(io.micronaut.http.MutableHttpHeaders) TooLongFrameException(io.netty.handler.codec.TooLongFrameException) InterfaceHttpData(io.netty.handler.codec.http.multipart.InterfaceHttpData) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) StringUtils(io.micronaut.core.util.StringUtils) CompositeByteBuf(io.netty.buffer.CompositeByteBuf) HttpClientFilter(io.micronaut.http.filter.HttpClientFilter) StreamedHttpRequest(io.micronaut.http.netty.stream.StreamedHttpRequest) io.netty.handler.codec.http(io.netty.handler.codec.http) StreamingHttpClient(io.micronaut.http.client.StreamingHttpClient) WebSocketSessionException(io.micronaut.websocket.exceptions.WebSocketSessionException) Type(java.net.Proxy.Type) Socks5ProxyHandler(io.netty.handler.proxy.Socks5ProxyHandler) ClientWebSocket(io.micronaut.websocket.annotation.ClientWebSocket) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) ClientServerContextFilter(io.micronaut.http.client.filters.ClientServerContextFilter) LoggingHandler(io.netty.handler.logging.LoggingHandler) UriBuilder(io.micronaut.http.uri.UriBuilder) HttpPostRequestEncoder(io.netty.handler.codec.http.multipart.HttpPostRequestEncoder) FluxSink(reactor.core.publisher.FluxSink) DefaultHttpDataFactory(io.netty.handler.codec.http.multipart.DefaultHttpDataFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HttpClientFilterResolver(io.micronaut.http.filter.HttpClientFilterResolver) Scheduler(reactor.core.scheduler.Scheduler) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) WebSocketBeanRegistry(io.micronaut.websocket.context.WebSocketBeanRegistry) BeanMap(io.micronaut.core.beans.BeanMap) NoopAddressResolverGroup(io.netty.resolver.NoopAddressResolverGroup) WebSocketVersion(io.netty.handler.codec.http.websocketx.WebSocketVersion) BlockingHttpClient(io.micronaut.http.client.BlockingHttpClient) ByteBuf(io.netty.buffer.ByteBuf) Charset(java.nio.charset.Charset) HttpClientException(io.micronaut.http.client.exceptions.HttpClientException) io.netty.channel(io.netty.channel) Schedulers(reactor.core.scheduler.Schedulers) HttpResponseWrapper(io.micronaut.http.HttpResponseWrapper) Subscriber(org.reactivestreams.Subscriber) MediaTypeCodec(io.micronaut.http.codec.MediaTypeCodec) Logger(org.slf4j.Logger) DefaultRequestBinderRegistry(io.micronaut.http.bind.DefaultRequestBinderRegistry) MalformedURLException(java.net.MalformedURLException) AnnotationMetadataResolver(io.micronaut.core.annotation.AnnotationMetadataResolver) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener) ApplicationProtocolNames(io.netty.handler.ssl.ApplicationProtocolNames) DefaultHttpClientFilterResolver(io.micronaut.http.client.filter.DefaultHttpClientFilterResolver) Http2Content(io.micronaut.http.netty.stream.Http2Content) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) NonNull(io.micronaut.core.annotation.NonNull) IdleStateHandler(io.netty.handler.timeout.IdleStateHandler) ByteBufUtil(io.netty.buffer.ByteBufUtil) EmptyByteBuf(io.netty.buffer.EmptyByteBuf) CollectionUtils(io.micronaut.core.util.CollectionUtils) Subscription(org.reactivestreams.Subscription) Closeable(java.io.Closeable) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) AbstractChannelPoolMap(io.netty.channel.pool.AbstractChannelPoolMap) JsonSubscriber(io.micronaut.http.netty.stream.JsonSubscriber) InputStream(java.io.InputStream) NettyHttpHeaders(io.micronaut.http.netty.NettyHttpHeaders) MutableHttpHeaders(io.micronaut.http.MutableHttpHeaders) OnMessage(io.micronaut.websocket.annotation.OnMessage) URI(java.net.URI) NettyWebSocketClientHandler(io.micronaut.http.client.netty.websocket.NettyWebSocketClientHandler) HttpClientException(io.micronaut.http.client.exceptions.HttpClientException) Bootstrap(io.netty.bootstrap.Bootstrap) SslContext(io.netty.handler.ssl.SslContext) Duration(java.time.Duration) NettyHttpHeaders(io.micronaut.http.netty.NettyHttpHeaders) WebSocketVersion(io.netty.handler.codec.http.websocketx.WebSocketVersion) WebSocketSessionException(io.micronaut.websocket.exceptions.WebSocketSessionException) IdleStateHandler(io.netty.handler.timeout.IdleStateHandler) ReadTimeoutHandler(io.netty.handler.timeout.ReadTimeoutHandler) ClientWebSocket(io.micronaut.websocket.annotation.ClientWebSocket) MutableHttpHeaders(io.micronaut.http.MutableHttpHeaders)

Aggregations

Internal (io.micronaut.core.annotation.Internal)5 RequestBinderRegistry (io.micronaut.http.bind.RequestBinderRegistry)5 MediaTypeCodecRegistry (io.micronaut.http.codec.MediaTypeCodecRegistry)5 WebSocketBean (io.micronaut.websocket.context.WebSocketBean)5 HttpRequest (io.micronaut.http.HttpRequest)4 CloseReason (io.micronaut.websocket.CloseReason)4 Channel (io.netty.channel.Channel)4 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)4 SimpleChannelInboundHandler (io.netty.channel.SimpleChannelInboundHandler)4 CloseWebSocketFrame (io.netty.handler.codec.http.websocketx.CloseWebSocketFrame)4 List (java.util.List)4 AtomicReference (java.util.concurrent.atomic.AtomicReference)4 Consumer (java.util.function.Consumer)4 Publisher (org.reactivestreams.Publisher)4 Logger (org.slf4j.Logger)4 LoggerFactory (org.slf4j.LoggerFactory)4 Flux (reactor.core.publisher.Flux)4 Schedulers (reactor.core.scheduler.Schedulers)4 NettyByteBufferFactory (io.micronaut.buffer.netty.NettyByteBufferFactory)3 NonNull (io.micronaut.core.annotation.NonNull)3