#spring-boot #websocket #jhipster #stomp #sockjs
#весенняя загрузка #websocket #jhipster #топать #sockjs
Вопрос:
Я пытаюсь подключиться к websocket в моем существующем приложении Jhipster, которое построено с использованием Java spring и Angular 8. Во время создания проекта я не выбрал опцию websocket, и теперь есть необходимость реализовать websocket в проекте. Я воспользовался помощью «https://www.jhipster.tech/using-websockets /» и попытался реализовать то же самое решение, но я получаю сообщение об ошибке рукопожатия. Я использую STOMP и SockJS для в websockets. Пожалуйста, дайте мне знать, что может быть причиной сбоя рукопожатия.
Вот конфигурация websocket.java-файл.
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
import hr.nic.vc.security.AuthoritiesConstants;
import java.security.Principal;
import org.springframework.http.server.*;
import java.util.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.server.*;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.*;
import org.springframework.web.socket.server.HandshakeInterceptor;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
@Configuration
@EnableWebSocketMessageBroker
public class WebsocketConfiguration implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config)
{
config.enableSimpleBroker("/topic");
//config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry
registry) {
registry.addEndpoint("/websocket/blog").setHandshakeHandler(defaultHandshakeHandler())
.setAllowedOrigins("*").withSockJS();
}
@Bean
public HandshakeInterceptor httpSessionHandshakeInterceptor() {
return new HandshakeInterceptor() {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
attributes.put(IP_ADDRESS, servletRequest.getRemoteAddress());
}
return true;
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
}
};
}
private DefaultHandshakeHandler defaultHandshakeHandler() {
return new DefaultHandshakeHandler() {
@Override
protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {
Principal principal = request.getPrincipal();
if (principal == null) {
Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS));
principal = new AnonymousAuthenticationToken("WebsocketConfiguration", "anonymous", authorities);
}
return principal;
}
};
}
}
И это файл безопасности websocket.
public class WebsocketSecurityConfiguration extends AbstractSecurityWebSocketMessageBrokerConfigurer {
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages)
{
messages.nullDestMatcher().authenticated().simpDestMatchers("/topic/blog")
.authenticated()
// matches any destination that starts with /topic/
// (i.e. cannot send messages directly to /topic/)
// (i.e. can’t subscribe to /topic/messages/* to get messages which is sent to
// /topic/messages-user)
.simpDestMatchers("/topic/**").authenticated();
// message types other than MESSAGE and SUBSCRIBE
//.simpTypeMatchers(SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE).denyAll()
// catch all
//.anyMessage().denyAll();
}
/**
* Disables CSRF for Websockets.
*/
@Override
protected boolean sameOriginDisabled() {
return true;
}
}
Вот метод connect, который вызывается после аутентификации для подключения websocket.
connect():void {
console.log("connect called"); //eslint-disable-line
// build absolute path, websocket doesn't fail during deploying with a context path
let url = '/websocket/blog';
url = this.location.prepareExternalUrl(url);
const authToken = this.authServerProvider.getToken();
if (authToken) {
url = '?access_token=' authToken;
}
const socket = new SockJS(url);
this.stompClient = Stomp.over(socket);
const headers = {};
this.stompClient.connect(headers, () => {
console.log("this is inside stompclient connect connect"); //eslint-disable-line
this.stompClient.subscribe('/topic/blog', data => {
console.log("This inside subscription"); //eslint-disable-line
this.listenerObserver.next(JSON.parse(data.body));
});
});
}
}
Токен авторизации передается с правильным значением. Следовательно, ошибки в авторизации нет.
Пожалуйста, дайте мне знать, если потребуется что-нибудь еще.
Я застрял на этом этапе уже довольно давно.
Ошибка:
WebSocket connection to 'ws://localhost:8080/websocket/blog/587/mklduqvp/websocket?access_token=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJoYXJkZWVwc2h1a2xhMDhAbmljLmluIiwiYXV0aCI6IlJPTEVfRU1QTE9ZRUUiLCJleHAiOjE2MDUyNDUwNjd9.DJ2HITaVAiaphd2yg3yPAiLrLI4n8MjszjBasC3zOHrC-73mFdltDPEYHihY16VzPv0rh6EYLj84zCBv37TDNA' failed: Error during WebSocket handshake: Unexpected response code: 200
Комментарии:
1. Вы пробовали создать новый проект с теми же настройками, что и у старого, и скопировать конфигурацию?
2. Да, я пробовал это. Все еще не повезло. Та же ошибка, что и выше.
3. Недавно созданный проект работает нормально. Я пытаюсь добавить конфигурацию websocket в существующий проект. Также я обновил ошибку. Пожалуйста, посмотрите
4. Версия Jhipster одинакова для нового и старого проекта. Да, я проверил журналы на стороне сервера, ошибок не было, только на стороне клиента эта ошибка была показана. Я не запускал сервер в отладчике, поскольку оба проекта совершенно разные.
5. Отладчик покажет вам выполнение в посреднике сообщений, который не является вашим кодом, поэтому он одинаков для обоих проектов, только его инициализация должна отличаться и вызывать разное поведение. Журналы сервера, вероятно, не находятся на уровне отладки
org.springframework.web.socket
, поэтому вы не можете видеть, что происходит с comapre.
Ответ №1:
В вашем DefaultHandshakeHandler вы можете попробовать аннотировать @Bean и установить значение public.
@Bean
public DefaultHandshakeHandler defaultHandshakeHandler() {
Комментарии:
1. Спасибо за ответ, но я уже пробовал это. Все еще получаю ту же ошибку.