2015-05-28 34 views
15

WebSockets in Spring è un argomento piuttosto nuovo che sto stancando di trovare un po 'di più.Spring WebSocket Connessione con SockJS a un dominio diverso

Il mio problema è con la connessione a un servizio da un dominio diverso, sto lavorando con Lineman che costruisce il front-end e Spring Boot quando si fa il back-end, con che ho queste app su due diversi porte: 8000 e 8080 su localhost.

Ho riscontrato problemi con l'intestazione 'Access-Control-Allow-Origin' ma l'ho risolto aggiungendo un filtro sul lato server che ha aggiunto l'origine consentita all'intestazione. Dopo questo ho iniziato a ottenere il seguente errore sulla connessione:

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

Non ho Primavera di sicurezza nel progetto quindi questo non è un problema di autorizzazione, i punti di errore a sockJS: that.xhr.send (carico utile); - dove il carico utile non è mai definito. Ho provato ma non sono riuscito a trovare la radice della chiamata da dove è stato possibile iniziare.

Stavo pensando se è necessario aggiungere alcune informazioni aggiuntive a SockJS e Stomp quando si imposta la connessione, ma non ci sono molti esempi e note in entrambe le pagine wiki di questi strumenti.

Qui sotto troverai il codice JS della connessione.

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

ho provato anche la creazione di un messageHandler in quanto ha la possibilità di impostare OriginAllowe durante la configurazione, ma non sono sicuro di come è collegato al broker.

Ultimo pensiero, questa configurazione funziona correttamente quando si esegue su una porta.

+0

Hai mai questo lavoro? Sto avendo lo stesso problema. – jax

+11

Ho ottenuto questo lavoro in un'applicazione di primavera impostando le origini consentite. 'registry.addEndpoint ('/ websocket/models'). setAllowedOrigins (" * "). withSockJS();' – jax

+0

Grazie mille a tutti e due. Ragazzi avete fatto la mia giornata. – havish

risposta

36

anwesr di Jax era corretta :)

Il metodo registerStompEndpoints ci dà la possibilità di impostare le origini ammessi. Abbiamo bisogno di aggiungerlo prima dell'opzione "withSockJs()".

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

Esiste anche una connessione da client mobili oltre a sockjs? – vthallam

5

A chiunque di arrivare a questo biglietto a causa della risposta Proibita 403 quando tenta di connettersi attraverso un SockJsClient a un diverso dominio:

Il problema sorge quando si cerca di fare un GET al/info Url, come parte dell'handshaking. La risposta restituisce in realtà un 200 tramite WGET e tramite browser. Solo tramite SockJsClient non funziona.

Dopo aver provato diverse soluzioni, l'unico che ha risolto il problema è scrivere una classe che implementa Transport e InfoReceiver. In questo modo lo sviluppatore può gestire direttamente questa parte dell'handshake. In pratica si effettua il lavoro nel metodo 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) { 
     ... 
    } 
} 

ho definito TransportType.XHR come tipo di trasporto.

+0

Dove hai posto questo codice? – TheUnreal

0

ho trovato questa soluzione acquistare la creazione di un filtro

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

dove l'hai posizionato? Hai dovuto fare più cambiamenti ma aggiungere questa classe? – TheUnreal

+0

lo metto nella cartella "config" sul mio pacchetto – Fabricelepro

0

Nel mio caso, ho dovuto aggiungere queste configuarations per ottenere SockJS/STOM di lavorare con 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"); 
    } 
}