Spring boot Websocket不适用于spring boot应用程序和角度前端

Spring boot Websocket不适用于spring boot应用程序和角度前端,spring-boot,websocket,jhipster,sockjs,Spring Boot,Websocket,Jhipster,Sockjs,我看了很多,尝试了很多,但我找不到问题的原因。。。 我有一个JHipster生成的应用程序,它由一个spring引导应用程序和一个角度前端组成,我想使用WebSocket进行更新。为此,我使用Stomp和SockJs 连接本身已不工作。 我得到以下错误: WebSocket connection to 'ws://localhost:9000/updates/websocket/447/xxudq4ni/websocket' failed: WebSocket is closed before

我看了很多,尝试了很多,但我找不到问题的原因。。。 我有一个JHipster生成的应用程序,它由一个spring引导应用程序和一个角度前端组成,我想使用WebSocket进行更新。为此,我使用Stomp和SockJs

连接本身已不工作。 我得到以下错误:

WebSocket connection to 'ws://localhost:9000/updates/websocket/447/xxudq4ni/websocket' failed: WebSocket is closed before the connection is established.
这是对端口9000的调用,然后它被代理到端口8080下的实际后端。 如果我直接调用端口8080下的后端,我会得到:

WebSocket connection to 'ws://localhost:8080/updates/websocket/156/mg0dspp2/websocket' failed: Error during WebSocket handshake: Unexpected response code: 200
我真的看不出实际的响应是什么,但我假设它是JHIpster错误消息“发生了错误”,并且返回的这个html的http状态码是200

我不知道实际的问题是什么。。。我跟踪了这个和其他几个。。。 这是我的后端:

WebsocketConfig:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    public static final String IP_ADDRESS = "IP_ADDRESS";

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry
            .addEndpoint("/updates/websocket")
            //.setHandshakeHandler(defaultHandshakeHandler())
            .setAllowedOrigins("*")
            .withSockJS()
            .setClientLibraryUrl("https://cdn.jsdelivr.net/npm/sockjs-client@1.5.0/dist/sockjs.min.js");
            //.setInterceptors(httpSessionHandshakeInterceptor());
    }

    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;
            }
        };
    }

    @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
            ) {}
        };
    }
}
@Controller
public class UpdateController  {
    private static final Logger log = LoggerFactory.getLogger(UpdateController.class);
    
    @MessageMapping("/updates/websocket")
    @SendTo("/topic/trucks")
    public UpdateDto send(UpdateDto dto) {
        return dto;
    }
}
 connect(): void {
        if (this.stompClient?.connected || this.called) {
            return;
        }
        this.called = true;
        // building absolute path so that websocket doesn't fail when deploying with a context path
        let url = '/updates/websocket';
        url = this.location.prepareExternalUrl(url);

        var socket = new SockJS(url);
        this.stompClient = Stomp.over(socket);

        this.stompClient.connect({}, (frame) => {
            this.connectionSubject.next();

            this.sendActivity();

            this.routerSubscription = this.router.events
                .pipe(filter((event: Event) => event instanceof NavigationEnd))
                .subscribe(() => this.sendActivity());
        }, error => {
            console.log(error);
        });
    }
前端:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    public static final String IP_ADDRESS = "IP_ADDRESS";

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry
            .addEndpoint("/updates/websocket")
            //.setHandshakeHandler(defaultHandshakeHandler())
            .setAllowedOrigins("*")
            .withSockJS()
            .setClientLibraryUrl("https://cdn.jsdelivr.net/npm/sockjs-client@1.5.0/dist/sockjs.min.js");
            //.setInterceptors(httpSessionHandshakeInterceptor());
    }

    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;
            }
        };
    }

    @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
            ) {}
        };
    }
}
@Controller
public class UpdateController  {
    private static final Logger log = LoggerFactory.getLogger(UpdateController.class);
    
    @MessageMapping("/updates/websocket")
    @SendTo("/topic/trucks")
    public UpdateDto send(UpdateDto dto) {
        return dto;
    }
}
 connect(): void {
        if (this.stompClient?.connected || this.called) {
            return;
        }
        this.called = true;
        // building absolute path so that websocket doesn't fail when deploying with a context path
        let url = '/updates/websocket';
        url = this.location.prepareExternalUrl(url);

        var socket = new SockJS(url);
        this.stompClient = Stomp.over(socket);

        this.stompClient.connect({}, (frame) => {
            this.connectionSubject.next();

            this.sendActivity();

            this.routerSubscription = this.router.events
                .pipe(filter((event: Event) => event instanceof NavigationEnd))
                .subscribe(() => this.sendActivity());
        }, error => {
            console.log(error);
        });
    }
我在Windows上运行Im,我使用Chrome进行开发。但它在FireFox中也不起作用,所以我认为它与平台无关。
任何帮助都将不胜感激。多谢各位

状态代码为200的错误无论如何都很奇怪。。但是:除了setClientLibraryUrl之外,您的配置看起来很好,与我的配置相似。检查的一个想法是:Jhipster创建一个安全配置,定义谁可以访问端点。当前用户(或者您可以使用permitAll)应该可以访问您的端点(更新/**)?!您的代码中是否有此更改?否则,websocket端点将被发送到
/index.html
在您的情况下,它可能需要
更新
而不是
websocket
,因为它与JHipster的websocket实现不同,状态代码为200的错误无论如何都很奇怪。。但是:除了setClientLibraryUrl之外,您的配置看起来很好,与我的配置相似。检查的一个想法是:Jhipster创建一个安全配置,定义谁可以访问端点。当前用户(或者您可以使用permitAll)应该可以访问您的端点(更新/**)?!您的代码中是否有此更改?否则,websocket端点将被发送到
/index.html
,在您的情况下,它可能需要
更新
,而不是
websocket
,因为它与JHipster的websocket实现不同