use of io.micronaut.http.netty.websocket.WebSocketSessionRepository 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);
}
});
}
Aggregations