Java Atmosphere Framework - 客户端onMessage从未调用

时间:2017-07-26 12:40:45

标签: javascript java spring-boot atmosphere

我有一个 Spring Boot 应用程序,我设法将 Atmosphere 聊天应用程序集成为一个概念验证,看看Beans和Configs是实际工作。

奇怪的是,如果我使用@ManagedService注释的类设置有点不同,我就无法启动Javascript request.onMessage函数。

我尝试使用不同的大气层服务(如@Resume@Suspend等)对类的方法进行注释,但仍然没有触发客户端onMessage函数。 (空浏览器控制台)

这是我的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);
        }

    }
}

这是我的@ManagedService课程:

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

这是我的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>

最后我的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);
});

1 个答案:

答案 0 :(得分:0)

在进一步调查此问题后,我发现为了触发后端代码的执行,必须事先调用前端javascript方法subSocket.push(xxx) 在客户端。

我最终在myAtmosphereApp.js

的客户端添加了此代码
function triggerBackend() {
    subSocket.push(someDataCollectedInFrontend);
}
setInterval(triggerBackend, 1000);

客户端代码每秒会触发onResume一次。