首页 > 解决方案 > SpringBoot SockJS 未声明 /info 路径

问题描述

StompJS 通过 SockJS 套接字通过 WebSocket 联系我的 SpringBoot 程序。或者至少我正试图让这种情况发生。以前,我有一个 CORS 错误;现在客户端报告 404。我相信它没有声明 SockJS 期望的 /info URL。我以为我做了所有我需要做的事情来让 SpringBoot 为我生成它。

我意识到 /info 是 SockJS 协议的一部分。我不明白为什么它没有为我生成。

Firefox 网络选项卡报告 404

GET https://localhost:8081/bluecost/ws/info?t=1628490888709
{
"timestamp":"2021-08-09T06:34:50.126+0000",
"status":404,
"error":"Not Found",
"message":"No message available",
"path":"/bluecost/ws/info"
}

softlayer.component.ts(片段)

    onChooseBlueReportFile(files: FileList) {
        console.log('@@@ onChooseBlueReportFile');
        this.blueReportSelected = true;
        this.blueReportFileName = files.item(0).name;
        this.blueReportFile = files.item(0);
        const pattern = /\d*[0-9]+[.]+\d{3}[0-9]$/;
        if (this.blueReportFileName == null || this.blueReportFileName == 'No file selected') {
            this.displayUploadBlueReportsError("No file selected.Please select one.");
        } else {
            this.errorBlueReport = false;
        }
        if (!this.errorBlueReport) {
            this.showLoaderBlueReport = true;
            var headers = {
            };
            var costFileClient = this.softlayerService.uploadCostFileAsync(this.blueReportFile);
            console.log('Before webService connect');
            var send_file = function(stompClient, input) {
                let file = input.files[0];
                read_file(file, (result => {
                    stompClient.send('/app/cost-file', { 'content-type': 'application/octet-stream' }, result)
                }))
            };

            var read_file = function (file, result) {
                const reader = new FileReader()
                reader.onload = function(e) {
                    var arrayBuffer = reader.result;
                }
                reader.readAsArrayBuffer(file)
            };

            costFileClient.connect(headers,
                /* Connect Callback */
                function(frame) {
                    console.log('@@ Connected: '+frame);
                    send_file(costFileClient,files);
                    costFileClient.subscribe("/topic/softlayer-cost-file",
                        /* Subscribe Callback */
                        function(data) {
                            console.log('Incoming response from send: '+data);
                        }
                    );
                    
                },
                /* Connect Error Callback*/
                function(error) {
                    console.log('@@@ Error on connect: ' + error);
                }
            );
            console.log('After webService connect');
        }
    }

软层服务.ts

  uploadCostFileAsync(file: File) {

    const reqOptions = {
      headers: new HttpHeaders({
        'X-Requested-With': 'XMLHttpRequest'
      })
    };
    let formData = new FormData();
    formData.append('file', file);
    const socket = new SockJS('https://localhost:8081/bluecost/ws');
    this.stompClient = Stomp.over(socket);
    return this.stompClient;
  }

WebSocketConfig.java

@Configuration
@EnableWebSocket
@Controller
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer
        implements WebSocketConfigurer, WebSocketMessageBrokerConfigurer {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketConfig.class);

    @Autowired
    CostFileUploadWebSocketHandler costFileUploadWebSocketHandler;

    @Override
    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
        messages.anyMessage().authenticated();
    }

    @Override
    protected boolean sameOriginDisabled() {
        return true;
    }

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        logger.info("In registerWebSocketHandlers");
//      registry.addHandler(new SocketTextHandler(), "/wst");
//      registry.addHandler(costFileUploadWebSocketHandler, "/wsb/softlayer-cost-file");

        registry
        .addHandler(costFileUploadWebSocketHandler, "/bluecost/ws")
        .setAllowedOrigins("*")
        .withSockJS()
        .setWebSocketEnabled(true)
        .setHeartbeatTime(25000)
        .setDisconnectDelay(5000);
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        logger.info("In registerStompEndpoints");
        registry
        .addEndpoint("/bluecost/ws")
        .setAllowedOrigins("https://localhost:8448","https://localhost:8081") /* Removed * */
        .withSockJS();
    }

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

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();

        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowCredentials(false);
        configuration.setAllowedMethods(Arrays.asList("GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE", "PATCH"));
        configuration.setAllowedHeaders(Arrays.asList("Accept","Content-Type", "Access-Control-Allow-Headers", "Origin",
                "x-requested-with", "Authorization"));
        configuration.setExposedHeaders(Arrays.asList("X-Auth-Token","Authorization"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

}

WebSocketController.java

@Controller
public class WebSocketController {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketController.class);

    @Autowired
    private SimpMessageSendingOperations messagingTemplate;

    @MessageMapping("/softlayer-cost-file")
    @SendTo("/topic/softlayer-cost-file")
    public String processMessageFromClient(@Payload String message) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        String name = mapper.readValue(message,Map.class).get("name").toString();
        return name;
    }
    
    @MessageExceptionHandler
    public String handleException(Throwable exception) {
        messagingTemplate.convertAndSend("/errors", exception.getMessage());
        return exception.getMessage();
    }

}

标签: spring-bootwebsocketsockjs

解决方案


推荐阅读