2017-07-26 1 views
0

J'ai un Boot Spring application dans laquelle je suis parvenu à intégrer la atmosphère application Chat comme une preuve de concept, de voir que les haricots et les configs sont travaille réellement.Java Framework Atmosphere - côté client onmessage jamais appelé

Chose étrange est, si je configure la classe annotée avec @ManagedService un peu différemment, je ne peux pas obtenir la fonction request.onMessage Javascript à feu.

J'ai essayé d'annoter les méthodes de la classe avec différents services Atmosphère comme @Resume, @Suspend etc., mais la fonction onMessage côté client n'a jamais été déclenchée. (Vide console navigateur)

Ceci est mon fichier de configuration Bean AtmosphereConfig.java:

package my.poc.com; 

import java.util.Collections;  
import javax.servlet.ServletContext; 
import javax.servlet.ServletException;  
import org.atmosphere.cpr.AtmosphereServlet; 
import org.atmosphere.cpr.ContainerInitializer; 
import org.springframework.boot.web.servlet.ServletContextInitializer; 
import org.springframework.boot.web.servlet.ServletRegistrationBean; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.core.Ordered; 
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 

@Configuration 
public class AtmosphereConfig { 
    @Bean 
    public EmbeddedAtmosphereInitializer atmosphereInitializer() { 
     return new EmbeddedAtmosphereInitializer(); 
    } 

    @Bean 
    public ServletRegistrationBean atmosphereServlet() { 
     ServletRegistrationBean registration = new ServletRegistrationBean(
       new AtmosphereServlet(), "/atmurl/*"); 

     registration.addInitParameter("org.atmosphere.interceptor.HeartbeatInterceptor" 
       + ".clientHeartbeatFrequencyInSeconds", "10"); 

     registration.setLoadOnStartup(0); 
     // Need to occur before the EmbeddedAtmosphereInitializer 
     registration.setOrder(Ordered.HIGHEST_PRECEDENCE); 
     return registration; 
    } 

    @Configuration 
    static class MvcConfiguration extends WebMvcConfigurerAdapter { 
     @Override 
     public void addViewControllers(ViewControllerRegistry registry) { 
      registry.addViewController("/poc.html"); 
     } 
    } 

    private static class EmbeddedAtmosphereInitializer extends ContainerInitializer 
      implements ServletContextInitializer { 
     @Override 
     public void onStartup(ServletContext servletContext) throws ServletException { 
      onStartup(Collections.<Class<?>> emptySet(), servletContext); 
     } 

    } 
} 

Ceci est ma @ManagedService classe:

package my.poc.com 

import org.atmosphere.config.service.Get; 
import org.atmosphere.config.service.ManagedService; 
import org.atmosphere.cpr.AtmosphereResource; 
import org.atmosphere.cpr.AtmosphereResourceEvent; 
import org.atmosphere.cpr.AtmosphereResourceEventListenerAdapter; 

@ManagedService(path = "/atmurl") 
public class AtmosphereService2 { 

    @Get 
    public void myGetImpl(final AtmosphereResource resource) { 
     System.out.println("@Get method called by: " + resource.uuid()); 
     AtmosphereResource currentRes = resource; 
     System.out.println(currentRes); 
     resource.addEventListener(new AtmosphereResourceEventListenerAdapter() { 
      @Override 
      public void onSuspend(final AtmosphereResourceEvent event) { 
       System.out.println("resource suspended: " + event.getResource()); 
      } 
      @Override 
      public void onResume(final AtmosphereResourceEvent event) { 
       System.out.println("resource resumed: " + event.getResource()); 
      } 
      @Override 
      public void onDisconnect(final AtmosphereResourceEvent event) { 
       if (event.isCancelled()) { 
        System.out.println("resource onDisconnect cancelled: " + event.getResource().uuid()); 
       } else if (event.isClosedByClient()) { 
        System.out.println("resource onDisconnect closedByClient: " + event.getResource().uuid()); 
       } 
      } 
     }); 
    } 
} 

Ceci est mon poc.html:

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8"> 
<title>Poc</title> 
<script type="text/javascript" src="js/atmosphere/jquery-2.0.3.js"></script> 
<script type="text/javascript" src="js/atmosphere/atmosphere.js"></script> 
<script type="text/javascript" src="js/atmosphere/myAtmosphereApp.js"></script> 
</head> 
<body> 
</body> 
</html> 

Et enfin mon myAtmosphereApp.js:

$(function() { 
    "use strict"; 
    console.log("application_2.js start"); 

    var socket = atmosphere; 
    var subSocket; 
    // Websocket does not work with AJP. 
    if (window.EventSource) { 
     var transport = 'sse'; 

    } else { 
     var transport = 'long-polling'; 
    } 

    var request = { 
     url : document.location.protocol + "//" + document.location.host + '/atmurl', 
     contentType : "application/json", 
     logLevel : 'debug', 
     transport : transport, 
     trackMessageLength : true, 
     enableProtocol : false, 
     fallbackTransport : 'long-polling' 
    }; 

    request.onOpen = function(response) { 
     console.log("request.onOpen called"); 
    } 

    request.onMessage = function(response) { 
     console.log("request.onMessage called"); 
    } 

    request.onClose = function(response) { 
     console.log("request.onClose called"); 
    } 

    subSocket = socket.subscribe(request); 
}); 

Répondre

0

Après avoir étudié la question plus loin, je trouve que pour déclencher l'exécution de code Backend, on doit appeler le javascript frontal méthode subSocket.push(xxx)avance sur le côté client.

Je fini par ajouter ce code sur le côté client dans myAtmosphereApp.js:

function triggerBackend() { 
    subSocket.push(someDataCollectedInFrontend); 
} 
setInterval(triggerBackend, 1000); 

Ce code côté client déclenche onResume chaque seconde fois.