我一直在尝试使用 jsf 中的 primefaces 实现一些基本的推送功能。我用过那里的反例http://www.primefaces.org/showcase-labs/push/counter.jsf http://www.primefaces.org/showcase-labs/push/counter.jsf。本质上它是一个增加共享计数器的按钮。运行此示例时,我总是收到此错误:
ERROR: MAC did not verify!
我的理解是,每个会话都会生成一个 mac,然后检查每条传入消息以验证源是否未更改(我认为)。我一直无法找到此问题的原因,并查看了其他线程,例如:
错误:MAC 未验证! PrimeFaces https://stackoverflow.com/questions/19521087/error-mac-did-not-verify-primefaces
JSF:Mojarra 2.1 到 2.2 迁移导致 ViewExpiredException https://stackoverflow.com/questions/19706327/jsf-mojarra-2-1-to-2-2-migration-causing-viewexpiredexception
不幸的是这些并没有解决我的问题。两者似乎都是由我没有得到的 ViewExpiredException 引起的。我发现阻止它的唯一方法是在 web.xml 中将状态保存方法从客户端更改为服务器:
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
但是,执行此操作时,计数器不再共享,而是显示为每个用户,这不是我想要的。我的最终目标是实现一个聊天室,它的大部分内容都在那里,但现在它使用短轮询,可扩展性不太好。看过primefaces推送后,我认为它是理想的,但一直在努力使用它。
我尝试过多个 Web 服务器(Tomcat、Jetty 和 Glassfish),并尝试使用不同版本的 JSF (Mojarra) 和 primefaces 版本(3.4 和 4.0)。我已经在多个浏览器和多台计算机上对其进行了测试。有时我可以在出现错误之前将计数器增加几次,有时它会立即发生。我没有遇到任何异常或服务器错误,并且一切都可以编译。我还想提一下,我之前在其他项目上也遇到过这个错误,但在重新启动服务器后它就消失了。当使用 primefaces Push 时,总会发生这种情况。任何帮助将不胜感激。
EDIT
当将状态保存到 web.xml 中的服务器以避免 MAC 错误时,我注意到共享计数器在同一台计算机上以每个浏览器为基础工作。这意味着如果我有多个选项卡或窗口,则一次更新所有选项卡或窗口即可更新计数器。但它不能跨浏览器工作,firefox 中计数器的更改不会反映在 chrome 或 IE 中,反之亦然。如果在两台独立的计算机上,它也不会反映出来。我不知道这是否有帮助,但我想我会提一下。
EDIT
在注意到示例中的 bean 是会话范围后,我将其更改为应用程序范围。当然,会话范围意味着每个浏览器都有自己的副本。现在,这些更改已反映在浏览器和计算机上。回到我原来的问题,我仍然想知道为什么将保存状态更改为服务器可以修复 MAC 错误,这意味着什么?我假设服务器现在必须维护每个会话的视图状态而不是客户端,可扩展性较低/客户端-服务器流量较多?根据我所读到的内容,如果将保存状态设置为服务器,则无法检查视图过期异常或阻止用户创建视图(如果用户已经拥有太多视图),这是正确的吗?