我有一个 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);
});
答案 0 :(得分:0)
在进一步调查此问题后,我发现为了触发后端代码的执行,必须事先调用前端javascript方法subSocket.push(xxx)
在客户端。
我最终在myAtmosphereApp.js
:
function triggerBackend() {
subSocket.push(someDataCollectedInFrontend);
}
setInterval(triggerBackend, 1000);
客户端代码每秒会触发onResume
一次。