我们有一个带有仪表板的 Web 应用程序,它不断地轮询更新。在服务器端,更新请求是异步的,因此我们可以通过监听器/通知系统在发生更新时做出响应。
我们看到的问题是,当其中一个轮询请求得到响应时,在某些情况下,它可能会写入请求/响应以获取用户点击的链接。
异步更新的传入请求如下所示:
@RequestMapping("/getDashboardStatus.json")
public void getDashboardStatus(HttpServletRequest request, ...) {
final AsyncContext asyncContext = request.startAsync();
// 10 seconds
asyncContext.setTimeout(10000);
asyncContext.start(new Runnable() {
public void run() {
// .. (code here waits for an update to occur) ..
sendMostRecentDashboardJSONToResponse(asyncContext.getResponse());
if (asyncContext.getRequest().isAsyncStarted()) {
asyncContext.complete();
}
}
});
}
奇怪的地方在于,这个仪表板上有指向其他页面的链接。每大约 100 次左右的点击,其中一次将而不是显示所选页面,实际上显示上面发送的 JSON!
例如,我们有一个单独的 MVC 方法:
@RequestMapping("/result/{resultId}")
public ModelAndView getResult(@PathVariable String resultId) {
return new ModelAndView(...);
}
当点击仪表板上访问 /result/1234 的链接时,每个蓝月亮,页面将加载 200 OK 状态,但不包含预期的 HTML,实际上包含轮询请求的 JSON!
每个客户端只允许一个请求吗?由单击的链接发起的请求是否会覆盖来自同一客户端的任何已经位于服务器端的异步请求?
我们如何管理这些请求以确保异步响应发送到 async 请求?
我注意到 AsyncContext 对象上有一个 hasOriginalRequestAndResponse() 方法,但我很难从 Javadoc 中理解它是否是我正在寻找的。
更新:我刚刚添加了一个这样的片段:
String requestURI = ((HttpServletRequest)asyncContext.getRequest()).getRequestURI());
System.out.println("Responding w/ Dashboard to: " + requestURI);
sendMostRecentDashboardJSONToResponse(asyncContext.getResponse(), clientProfileKey);
并且能够在正确行为期间重现该问题,我看到:
Responding w/ Dashboard to: /app/getDashboardStatus.json
但是当我看到 JSON 推送到点击发起的请求时,我看到了:
Responding w/ Dashboard to: null
最佳答案
我已经弄清楚了这一点。请求/响应 确实被回收了,所以通过卡在分配给 AsyncContext 的响应上,我正在写出与 关联的响应不同的请求。
调用 startAsync() 保证请求/响应对象在异步上下文完成之前不会被回收。尽管我发现没有地方会过早或错误地完成上下文,但它正在完成:
超时。
在没有服务器端 Activity 的情况下等待 10 多秒,让 JSON 更新请求超时,然后然后单击链接,我能够始终如一地重现此问题。超时后,与异步上下文相关的请求/响应超时,从而完成,从而回收。
我发现了两个解决方案。
首先是在上下文中添加一个AsyncListener,并跟踪是否发生了超时。当您的监听器检测到超时时,您会翻转一个 boolean,并在写入响应之前对其进行检查。
second 是在写入响应之前对请求简单地调用 isAsyncStarted()。如果上下文超时,此方法将返回 false。如果上下文仍然有效/等待,它将返回 true。
关于java - AsyncContext 响应与原始传入请求不匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27711105/
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie
我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我