微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Websocket 不适用于 Spring Boot 应用程序和 Angular 前端

如何解决Websocket 不适用于 Spring Boot 应用程序和 Angular 前端

我查看并尝试了很多,但我找不到问题的原因... 我有一个 JHipster 生成的应用程序,它由一个 Spring Boot 应用程序和一个有角度的前端组成,我想使用 websockets 进行更新。为此,我使用 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。

我不知道实际问题是什么......我关注了这个intro here和其他几个...... 这是我的后端:

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,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,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 上,我使用 Chrome 进行开发。但它在 FireFox 中也不起作用,所以我认为它与平台无关。 任何帮助将不胜感激。非常感谢!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。