所以我必须说所有的websocket教程/示例看起来都很简单,但是你似乎真的需要挖掘才能找到简单例子中遗漏的非常重要的信息.我的webapp使用前端有SockJS的Spring 4 Stomp消息代理,我有很多问题.
目前,如果我在没有启用SockJS()的情况下向StompEndpointRegistry添加端点,然后使用dojo的dojox/socket在前端声明我的套接字,Firefox 28将打开websocket就好了.但是,我需要在IE8和IE9中支持,所以我切换到了SockJS.使用AbstractAnnotationConfigDispatcherServletInitializer,我花了很多时间来弄清楚如何确保所有过滤器和servlet都设置为使用异步(在Web上非常稀疏的文档).一旦我解决了这个问题,我现在可以在Firefox中使用它,但只能使用xhr_streaming.将sessionCookieNeeded设置为true,IE9默认尝试使用iframe进行连接,但是,它失败:
LOG: Opening Web Socket...
LOG: Opening transport: iframe-htmlfile url:rest/hello/904/ft3apk1g RTO:1008
LOG: Closed transport: iframe-htmlfile SimpleEvent(type=close, code=1006, reason=Unable to load an iframe (onload timeout), wasClean=false)
LOG: Opening transport: iframe-xhr-polling url:rest/hello/904/bf63eisu RTO:1008
LOG: Closed transport: iframe-xhr-polling SimpleEvent(type=close, code=1006, reason=Unable to load an iframe (onload timeout), wasClean=false)
LOG: Whoops! Lost connection to undefined
Run Code Online (Sandbox Code Playgroud)
如果我将所需的cookie设置为false,IE将使用xdr-streaming并正常工作,但是,它会丢失请求中的jsessionid cookie,反过来我失去了在控制器中获取Principal的能力,这对我来说很重要.我在spring security中启用了相同的origin x frame header,我已经验证了请求中是否存在标题,但它没有帮助.所以我想知道如何A)让Spring和SockJS在Firefox中使用WebSocket传输正确协商,并且B)让IE8和9正确使用iframe传输,这样我就可以保留cookie.
这是我的配置/代码:
网络应用配置:
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
Map<String, ? …Run Code Online (Sandbox Code Playgroud) 我有一个Web应用程序,它接受一系列ID,一次查询每个ID的外部Web服务,并在每个结果通过STOMP代理到达WebSocket客户端时发布.我可以使用简单的Futures来使用它,但我正在尝试使用Spring 4的新ListenableFutures并提供回调.
工作代码使用我的root配置中定义的ThreadPoolTaskExecutor.我有一个名为"SosQuery"的类,其中一个名为"test"的方法使用@Async注释并返回AsyncResult.这是从根上下文服务类调用的工作代码:
@Override
public void test(String[] oids) throws Exception {
List<Future<String>> futures = new ArrayList<Future<String>>();
for (String oid : oids) {
futures.add(sosQuery.test(oid));
}
while (!futures.isEmpty()) {
List<Future<String>> done = new ArrayList<Future<String>>();
for (Future<String> future : futures) {
if (future.isDone()) {
messagingTemplate.convertAndSendToUser("me", "/queue/observation", future.get());
done.add(future);
}
}
futures.removeAll(done);
}
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,我看到响应到达我的客户端.我修改了使用@Async注释定义的SosQuery方法,只返回"String",并在我的root配置中创建了一个SimpleAsyncTaskExecutor.以下是使用ListenableFuture的修改方法:
@Override
public void test(String[] oids) throws Exception {
for (final String oid : oids) {
ListenableFuture<String> task = asyncTaskExecutor.submitListenable(new Callable<String>(){
@Override
public String call() throws Exception {
String result …Run Code Online (Sandbox Code Playgroud) 有人可以帮我转换下面的代码来使用方法引用吗?我试图绕过这个新语法,但是当它变得比单个变量映射到单个方法调用更复杂时,我很快就会迷失:
getWorkspaces().stream().forEach((ws) -> {
DataStoreInfo defaultDataStore = getDefaultDataStore(ws);
if (defaultDataStore != null) {
other.setDefaultDataStore(ws, defaultDataStore);
}
});
Run Code Online (Sandbox Code Playgroud)
我从这开始,但它不起作用:)
getWorkspaces().stream()
.map(this::getDefaultDataStore)
.filter(Objects::nonNull)
.map(other::setDefaultDataStore);
Run Code Online (Sandbox Code Playgroud)
编辑:通过"它不起作用",我的意思是IDE在"setDefaultDataStore"下的最后一行抱怨它无法解析该方法.我希望我能从一些有用的东西开始,但我不知道如何到达那里.我很困惑如何使用方法引用来调用一个带有2个参数的方法以及如何映射它.我已经转换了一些看起来像这样的代码:
getMaps().stream().forEach((m) -> {
other.add(m);
});
Run Code Online (Sandbox Code Playgroud)
对此:
getMaps().forEach(other::add);
Run Code Online (Sandbox Code Playgroud)
但是当它变得更复杂时我会迷失方向.我希望有一个明显的解决方案,如何使用方法引用编写相同的代码.
我希望这个问题不是太模糊,但我觉得我错过了一些基本的东西。这就是我所处的情况。我们有一个胖客户端应用程序,它在每个用户的本地计算机 (Windows 7) 上运行,并提供一个 JavaScript API 来与应用程序交互。我们有一个托管在服务器上的 Web 应用程序,但向 localhost 发出 AJAX 请求以与胖客户端 JS API 交互。
在一台机器上,我们加载 Web 应用程序。对 localhost 发出的所有 AJAX 请求都是在没有 OPTIONS 预检请求的情况下发出的。JS 控制台的 net 选项卡显示正在制作的 POST,并且响应成功(我可以告诉胖客户端在响应中包含哪些标头,包括所有必要的 CORS 标头)。
在另一台机器上,我们从同一台服务器加载 Web 应用程序。但是,当向本地主机发出 AJAX 请求时,会发出(预期的)OPTIONS 请求。不幸的是,胖客户端没有响应适当的 Access-Control-Allow-Origin 标头,因此不允许进行后续的 POST。
浏览器无关紧要,我们已经测试了最新版本的 Firefox 和 Chrome,我们总是从机器上得到相同的行为。我们已经在 4 台机器上进行了测试——2 台发送 OPTIONS,2 台只发送没有前面 OPTIONS 的 POST。似乎由浏览器决定 AJAX 目标是否与源不同以及它是否发送预检请求。我终生无法弄清楚为什么我的机器不发送任何 OPTIONS 请求,即使 AJAX 请求(到 localhost 或 lvh.me)是与网页源不同的主机/域,但从另一台机器加载相同的页面确实会产生它们。
是否有某种浏览器设置会影响这一点?还是 Windows 设置?为什么我们会在这方面看到不同的行为?
更新1:
为了简化和澄清,我有两台机器,machineA 和 machineB。两台机器都从远程服务器 example.com 加载 Web 应用程序。两台机器都在它们的本地机器上安装了一个完整的厚应用程序,提供了一个 Web 服务器和 API。从example.com 加载的Web 应用程序包含用于向本地主机提交AJAX 请求的JavaScript 代码,以便每个用户都可以与他们自己的胖客户端应用程序本地实例进行交互。由于 localhost …
java ×2
spring ×2
ajax ×1
cors ×1
cross-domain ×1
java-8 ×1
java-stream ×1
jquery ×1
lambda ×1
preflight ×1
sockjs ×1
stomp ×1
threadpool ×1
websocket ×1