我已经对即将提出的问题有了答案。
在任何情况下,我在这里询问它,以便它可以帮助从JEE 6迁移到JEE 7的人,以及那些正在考虑使用websocket的人——例如,用websocket功能代替长轮询。
问题:在支持JEE 7的Weblogic 12.2.1.2中,并尝试使用以下指南设置websocket:http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/HomeWebsocket/WebsocketHome.html
注意:上面的指南非常简单,它所说的都是正确的,"应该"有效。在你的应用程序中不一定有效,就像在我的应用程序上一样。但在概念上它应该。
尽管如此。websocket应用程序在从浏览器到备份的握手过程中出错,在握手过程中,HTTP连接应该升级为tcp/ip网络套接字连接。
Weblogic抱怨tyrus无法使用Ascyn-servlet行为来处理此握手协议。下面列出了握手期间错误的堆栈跟踪:
2017-01-23 14:54:59065线程ID:53错误HTTP-[ServletContext@129852715[应用程序:primefaces-60模块:primefaces-60路径:null规范版本:3.1]]Servlet失败,出现异常<[ACTIVE]队列的ExecuteThread:"5"'weblogic.kernel.Default(自调优)'>java.lang.IllegalStateException:此上禁用异步支持请求:weblogic.servlet.internal.ServletRequestImpl@2c87c663[得到/primefaces-60/actions HTTP/1.1连接:升级Pragma:无缓存缓存控制:无缓存升级:websocket来源:http://localhost:7001Sec WebSocket版本:13用户代理:Mozilla/5.0(Windows NT 6.1;WOW64)AppleWebKit/537.36(KHTML等Gecko)Chrome/55.0283.87 Safari/537.36 DNT:1接受编码:gzip,deflate、sdch、br接受语言:en-US,en;q=0.8,pt pt;q=0.6,pt;q=0.4,fr;q=0.2,它;q=0.2,de;q=0.2Sec WebSocket密钥:flKcAkxO3JBIc8cYfwvlA==Sec WebSSocket扩展:渗透率降低;客户端_max_window_bits
]在weblogic.servlet.internal.ServletRequestImpl.startAsync(servlet请求Impl.java:2029)在weblogic.servlet.internal.ServletRequestImpl.startAsync(servlet请求Impl.java:2005)在javax.servlet.ServletRequestWrapper.startAsync(servlet请求包装.java:432)在weblogic.websocket.tyrus.TyrusServlet过滤器.doFilter(TyrusServlet过滤器.java:241)在weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)在过滤器处。DummyTimeoutFilter2.doFilter(DummyTTimeoutFilter2.java:81)在weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)在weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:32)在weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)在weblogic.servlet.internal.WebAppServlet上下文$ServletInvocationAction.wrapaRun(WebAppServlet上下文.java:3683)在weblogic.servlet.internal.WebAppServlet上下文$ServletInvocationAction.run(WebAppServlet上下文.java:3649)在weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:326)在weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)在weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)在weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubject Handle.java:71)在weblogic.servlet.internal.WebAppServlet上下文.doSecuredExecute(WebAppServlet上下文.java:2433)在weblogic.servlet.internal.WebAppServlet上下文.securedExecute(WebAppServlet上下文.java:2281)在weblogic.servlet.internal.WebAppServlet上下文.execute(WebAppServlet上下文.java:2259)在weblogic.servlet.internal.ServletRequestImpl.runInternal(servlet请求Impl.java:1691)在weblogic.servlet.internal.ServletRequestImpl.run(servlet请求Impl.java:1651)在weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:270)在weblogic.invocation.ComponentInvocationContextManager_runAs(ComponentInvocationContextManager.java:348)在weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:333)在weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtilities.java:54)在weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)在weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManager Impl.java:640)位于的weblogic.work.ExecuteThread.execute(ExecuteThread.java:406)weblogic.work.ExecuteThread.run(ExecuteThread.java:346)
基于这样一种假设,即设置websocket端点的后端代码是完美的,并且用于尝试建立websocket连接的javascript代码也是完美的。森博迪能按照字母指南解释为什么会出现上述错误吗?
注意:-根据对实际应用程序的分析,上面的堆栈跟踪已经在一个具有工作websocket端点的示例应用程序中隔离,该应用程序已损坏为上面的异常。
答案很简单,一旦你知道了。。。如果没有人支持正确的解决方案,我将在一天左右的时间内回答。
回答我自己的问题。
应用程序在尝试打开web套接字连接时遇到的问题与tyrus使用Sevlet 3.0特定功能(即异步servlet处理)有关。
即使是在最琐碎的web应用程序上,也可能有过滤器,可以交叉应用于所有web请求。例如具有过滤器映射/*的过滤器。
这正是问题所在。正如下面的参考资料中所解释的,为了允许异步servlet运行通向servlet的整个过滤器链,服务器必须支持异步请求处理。
https://blogs.oracle.com/enterprisetechtips/entry/asynchronous_support_in_servlet_3
需要asyncSupported属性来区分编写的代码用于从为在异步上下文。事实上,对于使用异步功能,整个请求处理链必须具有通过注释或在其部署描述符。如果应用程序尝试启动异步操作,但出现请求处理链中的servlet或servlet过滤器不支持异步处理。
因此,为了解决这个问题,必须为过滤器集添加一个额外的元素:
<async-supported>true</async-supported>
例如:
<filter>
<filter-name>AFilter</filter-name>
<filter-class>webapp.AFilter</filter-class>
<async-supported>true</async-supported>
</filter>
在上面的堆栈跟踪的情况下,要使问题在独立应用程序中重现,所需要的就是添加一个伪过滤器,该过滤器除了将请求传递给下一个过滤器之外,什么都不做。过滤器为:DummyTimeoutFilter2。声明此筛选器时没有使用支持的async true。
最后,请注意,您的容器可能需要异步servlet来打开web套接字。如果你有任何过滤器来接收对你的websocket端点的请求,你可能会对这样的副作用感到惊讶。JEE6的应用程序尤其如此,但任何全新的JEE7应用程序都很容易出现这种情况。
然而,大多数人可能没有过滤器来拦截对websocket端点的调用。。。