2015-05-28 21 views
15

WebSockets in Spring là một chủ đề khá mới mà tôi rất mệt mỏi khi tìm kiếm thêm một chút.Spring WebSocket Kết nối với SockJS đến một miền khác

Vấn đề của tôi là kết nối với một dịch vụ từ một miền khác, tôi đang làm việc với Lineman xây dựng mặt trước và Spring Boot khi thực hiện back-end, với các ứng dụng này cổng: 8000 và 8080 trên máy chủ cục bộ.

Tôi gặp sự cố với tiêu đề 'Access-Control-Allow-Origin' nhưng tôi đã giải quyết vấn đề bằng cách thêm bộ lọc ở phía máy chủ đã thêm nguồn gốc được phép vào tiêu đề. Sau đó tôi bắt đầu nhận được lỗi sau trên kết nối:

GET http://localhost:8080/socket/info 403 (Forbidden) 
AbstractXHRObject._start @ sockjs-0.3.4.js:807 
(anonymous function) @sockjs-0.3.4.js:841 

tôi không có mùa xuân an ninh trong dự án vì vậy đây không phải là một vấn đề ủy quyền, các điểm lỗi để sockJS: that.xhr.send (khối hàng); - nơi tải trọng không bao giờ được xác định. Tôi đã thử nhưng không thể tìm thấy thư mục gốc của cuộc gọi nơi có thể bắt đầu. Tôi đã suy nghĩ nếu tôi cần thêm một số thông tin bổ sung cho SockJS và Stomp khi thiết lập kết nối, nhưng không có nhiều ví dụ và ghi chú trong cả hai trang wiki của công cụ này.

Dưới đây bạn sẽ tìm thấy mã JS kết nối.

var socket = new SockJS("http://localhost:8080/socket"); 
client = Stomp.over(socket); 

client.connect({'login': BoatsGame.userName, 
        'passcode': 'guest'}, 
      function (frame) { 
.... 

The Server Side has a MessageBroker configured :  


@Configuration 
@EnableWebSocketMessageBroker 
public class MessageBrokerConfig extends AbstractWebSocketMessageBrokerConfigurer { 

@Bean 
public ServletServerContainerFactoryBean createWebSocketContainer() { 
    ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean(); 
    container.setMaxTextMessageBufferSize(8192); 
    container.setMaxBinaryMessageBufferSize(8192); 
    return container; 
} 

@Override 
public void configureMessageBroker(MessageBrokerRegistry config) { 
    //config.enableStompBrokerRelay("/queue", "/topic"); 
    config.enableSimpleBroker("/queue", "/topic","/user"); 
    config.setApplicationDestinationPrefixes("/BoatBattleGame"); 
} 

@Override 
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { 
    stompEndpointRegistry.addEndpoint("/socket").withSockJS(); 
} 
} 

Tôi cũng đã cố gắng thiết lập MessageHandler vì nó có tùy chọn đặt OriginAllowe khi định cấu hình, nhưng tôi không chắc chắn cách thức kết nối với nhà môi giới.

Cuối cùng, thiết lập này hoạt động chính xác khi chạy trên một cổng.

+0

Bạn đã bao giờ có được điều này đang làm việc? Tôi gặp vấn đề tương tự. – jax

+11

Tôi đã làm việc này trong một ứng dụng mùa xuân bằng cách thiết lập nguồn gốc được cho phép. 'registry.addEndpoint ('/ websocket/models'). setAllowedOrigins (" * "). withSockJS();' – jax

+0

Cảm ơn bạn rất nhiều. Các bạn đã làm cho ngày của tôi. – havish

Trả lời

36

anwesr Jax là đúng :)

Phương pháp registerStompEndpoints mang đến cho chúng tôi cơ hội để thiết lập nguồn gốc phép. Chúng ta cần thêm nó trước tùy chọn "withSockJs()".

@Override 
    public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { 
     stompEndpointRegistry.addEndpoint("/BO/socket").setAllowedOrigins("*").withSockJS(); 
    } 
+0

Điều này cũng kết nối từ khách hàng di động ngoài sockjs? – vthallam

5

Để bất cứ ai nhận được để vé này vì câu trả lời Forbidden 403 khi cố gắng kết nối thông qua một SockJsClient đến một tên miền khác:

Vấn đề nảy sinh khi cố gắng để làm một GET đến/info Url, như một phần của việc bắt tay. Phản hồi thực sự trả về 200 qua WGET cũng như thông qua trình duyệt. Chỉ thông qua SockJsClient nó không hoạt động.

Sau khi thử các giải pháp khác nhau, là người duy nhất mà thực sự cố định vấn đề này là để viết một lớp mà thực hiện Giao thông vận tải và InfoReceiver. Bằng cách này, nhà phát triển có thể trực tiếp xử lý phần này của cái bắt tay. Về cơ bản bạn thực hiện công việc trong phương pháp executeInfoRequest():

@Override 
public String executeInfoRequest(URI infoUrl, HttpHeaders headers) { 
    HttpGet getRequest = new HttpGet(infoUrl); // eventually add headers here 
    HttpClient client = HttpClients.createDefault(); 

    try { 
     HttpResponse response = client.execute(getRequest); 
     List<String> responseOutput = IOUtils.readLines(response.getEntity().getContent()); 

     return responseOutput.get(0); 
    } catch (IOException ioe) { 
     ... 
    } 
} 

tôi xác định TransportType.XHR as type vận chuyển.

+0

Bạn đã đặt mã này ở đâu? – TheUnreal

0

tôi tìm thấy giải pháp này mua tạo ra một bộ lọc

package com.diool.notif.config; 

import org.slf4j.LoggerFactory; 
import org.springframework.stereotype.Component; 

import javax.servlet.*; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import java.io.IOException; 

@Component 
public class SimpleCORSFilter implements Filter { 

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(SimpleCORSFilter.class); 
    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
     LOGGER.info("Initilisation du Middleware"); 
    } 

    @Override 
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
     HttpServletRequest requestToUse = (HttpServletRequest)servletRequest; 
     HttpServletResponse responseToUse = (HttpServletResponse)servletResponse; 

     responseToUse.setHeader("Access-Control-Allow-Origin",requestToUse.getHeader("Origin")); 
     filterChain.doFilter(requestToUse,responseToUse); 
    } 

    @Override 
    public void destroy() { 

    } 
} 
+0

bạn đã đặt nó ở đâu? Bạn phải thực hiện nhiều thay đổi hơn nhưng thêm lớp này? – TheUnreal

+0

tôi đặt nó bên trong thư mục "config" trên gói của tôi – Fabricelepro

0

Trong trường hợp của tôi, tôi đã có thêm những configuarations để có được SockJS/STOM để làm việc với CORS:

@Configuration 
@EnableWebMvc 
public class WebConfig implements WebMvcConfigurer 
{ 
    @Override 
    public void addCorsMappings(CorsRegistry registry) { 
     registry.addMapping("/**") 
       .allowedOrigins("*") 
       .allowCredentials(false) 
       .maxAge(3600) 
       .allowedHeaders("Accept", "Content-Type", "Origin", 
"Authorization", "X-Auth-Token") 
       .exposedHeaders("X-Auth-Token", "Authorization") 
       .allowedMethods("POST", "GET", "DELETE", "PUT", "OPTIONS"); 
    } 
} 
Các vấn đề liên quan