use of io.micronaut.websocket.exceptions.WebSocketClientException in project micronaut-core by micronaut-projects.
the class NettyWebSocketClientHandler method channelRead0.
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) {
final Channel ch = ctx.channel();
if (!handshaker.isHandshakeComplete()) {
// web socket client connected
FullHttpResponse res = (FullHttpResponse) msg;
this.handshakeResponse = res;
try {
handshaker.finishHandshake(ch, res);
} catch (Exception e) {
try {
emitter.error(new WebSocketClientException("Error finishing WebSocket handshake: " + e.getMessage(), e));
} finally {
// clientSession isn't set yet, so we do the close manually instead of through session.close
ch.writeAndFlush(new CloseWebSocketFrame(CloseReason.INTERNAL_ERROR.getCode(), CloseReason.INTERNAL_ERROR.getReason()));
ch.close();
}
return;
}
handshakeFuture.setSuccess();
this.clientSession = createWebSocketSession(ctx);
T targetBean = genericWebSocketBean.getTarget();
if (targetBean instanceof WebSocketSessionAware) {
((WebSocketSessionAware) targetBean).setWebSocketSession(clientSession);
}
ExecutableBinder<WebSocketState> binder = new DefaultExecutableBinder<>();
BoundExecutable<?, ?> bound = binder.tryBind(messageHandler.getExecutableMethod(), webSocketBinder, new WebSocketState(clientSession, originatingRequest));
List<Argument<?>> unboundArguments = bound.getUnboundArguments();
if (unboundArguments.size() == 1) {
this.clientBodyArgument = unboundArguments.iterator().next();
} else {
this.clientBodyArgument = null;
try {
emitter.error(new WebSocketClientException("WebSocket @OnMessage method " + targetBean.getClass().getSimpleName() + "." + messageHandler.getExecutableMethod() + " should define exactly 1 message parameter, but found 2 possible candidates: " + unboundArguments));
} finally {
if (getSession().isOpen()) {
getSession().close(CloseReason.INTERNAL_ERROR);
}
}
return;
}
if (pongHandler != null) {
BoundExecutable<?, ?> boundPong = binder.tryBind(pongHandler.getExecutableMethod(), webSocketBinder, new WebSocketState(clientSession, originatingRequest));
List<Argument<?>> unboundPongArguments = boundPong.getUnboundArguments();
if (unboundPongArguments.size() == 1 && unboundPongArguments.get(0).isAssignableFrom(WebSocketPongMessage.class)) {
this.clientPongArgument = unboundPongArguments.get(0);
} else {
this.clientPongArgument = null;
try {
emitter.error(new WebSocketClientException("WebSocket @OnMessage pong handler method " + targetBean.getClass().getSimpleName() + "." + messageHandler.getExecutableMethod() + " should define exactly 1 pong message parameter, but found: " + unboundArguments));
} finally {
if (getSession().isOpen()) {
getSession().close(CloseReason.INTERNAL_ERROR);
}
}
return;
}
}
Optional<? extends MethodExecutionHandle<?, ?>> opt = webSocketBean.openMethod();
if (opt.isPresent()) {
MethodExecutionHandle<?, ?> openMethod = opt.get();
WebSocketState webSocketState = new WebSocketState(clientSession, originatingRequest);
try {
BoundExecutable openMethodBound = binder.bind(openMethod.getExecutableMethod(), webSocketStateBinderRegistry, webSocketState);
Object target = openMethod.getTarget();
Object result = openMethodBound.invoke(target);
if (Publishers.isConvertibleToPublisher(result)) {
Publisher<?> reactiveSequence = Publishers.convertPublisher(result, Publisher.class);
Flux.from(reactiveSequence).subscribe(o -> {
}, error -> emitter.error(new WebSocketSessionException("Error opening WebSocket client session: " + error.getMessage(), error)), () -> {
emitter.next(targetBean);
emitter.complete();
});
} else {
emitter.next(targetBean);
emitter.complete();
}
} catch (Throwable e) {
emitter.error(new WebSocketClientException("Error opening WebSocket client session: " + e.getMessage(), e));
if (getSession().isOpen()) {
getSession().close(CloseReason.INTERNAL_ERROR);
}
}
} else {
emitter.next(targetBean);
emitter.complete();
}
return;
}
if (msg instanceof WebSocketFrame) {
handleWebSocketFrame(ctx, (WebSocketFrame) msg);
} else {
ctx.fireChannelRead(msg);
}
}
Aggregations