【问题标题】:Java Atmosphere Framework - Client-side onMessage never calledJava Atmosphere Framework - 客户端 onMessage 从未调用
【发布时间】:2017-07-26 12:40:45
【问题描述】:

我有一个 Spring Boot 应用程序,我设法将 Atmosphere 聊天应用程序集成到其中作为概念验证,以查看 Bean 和配置是实际工作。

奇怪的是,如果我设置带有 @ManagedService 注释的类有点不同,我无法触发 Javascript request.onMessage 函数。

我尝试使用不同的 Atmosphere Services 注释类的方法,例如 @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);
});

【问题讨论】:

    标签: javascript java spring-boot atmosphere


    【解决方案1】:

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

    我最终在myAtmosphereApp.js 的客户端添加了这段代码:

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

    该客户端代码将每秒触发一次onResume

    【讨论】:

      猜你喜欢
      • 2017-01-02
      • 1970-01-01
      • 2017-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多