Weblogic 12.2.1.2 - websocket endpoint - 对此请求禁用了异步支持

时间:2017-01-23 14:52:22

标签: servlets asynchronous websocket weblogic tyrus

我已经回答了我即将提出的问题。

在任何问题中,我在这里问它,以便它可以帮助人们从JEE 6迁移到JEE 7并且正在考虑使用websocket - 例如用websocket功能替换长轮询。

问题: 在Weblogic 12.2.1.2中,它支持JEE 7,并尝试使用如下指南设置websockets: http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/HomeWebsocket/WebsocketHome.html

注意:上面的指南非常简单,所说的都是正确的,"应该"工作。不一定适用于您的应用程序,因为它在我的应用程序中没有。但在概念上它应该。

尽管如此。 在从浏览器到支持的握手期间,websocket应用程序出错,其中HTTP连接应该升级到tcp / ip Web套接字连接。

Weblogic,抱怨tyrus不能使用Ascyn servlet行为来处理这种握手协议。 接下来列出了握手期间错误的堆栈跟踪:

  2017-01-23 14:54:59,065 ThreadId:53错误HTTP - [ServletContext @ 129852715 [app:primefaces-60 module:primefaces-60      

path:null spec-version:3.1]] Servlet因异常而失败    < [ACTIVE] ExecuteThread:' 5'对于队列:   ' weblogic.kernel.Default(自我调整)'>   java.lang.IllegalStateException:对此禁用了async-support   要求:weblogic.servlet.internal.ServletRequestImpl@2c87c663 [GET   / primefaces-60 / actions HTTP / 1.1连接:升级Pragma:no-cache   缓存控制:无缓存升级:websocket来源:   http://localhost:7001 Sec-WebSocket-Version:13 User-Agent:   Mozilla / 5.0(Windows NT 6.1; WOW64)AppleWebKit / 537.36(KHTML,如   Gecko)Chrome / 55.0.2883.87 Safari / 537.36 DNT:1接受编码:gzip,   deflate,sdch,br接受语言:   的en-US,连接; Q = 0.8,PT-PT; Q = 0.6,PT; Q = 0.4,FR,Q = 0.2,它; Q = 0.2,DE; Q = 0.2   Sec-WebSocket-Key:flKcAkxO3CJBIc8cYvwvlA == Sec-WebSocket-Extensions:   permessage,放气; client_max_window_bits

     

]   weblogic.servlet.internal.ServletRequestImpl.startAsync(ServletRequestImpl.java:2029)     在   weblogic.servlet.internal.ServletRequestImpl.startAsync(ServletRequestImpl.java:2005)     在   javax.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:432)     在   weblogic.websocket.tyrus.TyrusServletFilter.doFilter(TyrusServletFilter.java:241)     在   weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)     at filter.DummyTimeoutFilter2.doFilter(DummyTimeoutFilter2.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.WebAppServletContext $ ServletInvocationAction.wrapRun(WebAppServletContext.java:3683)     在   weblogic.servlet.internal.WebAppServletContext $ ServletInvocationAction.run(WebAppServletContext.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(WlsSubjectHandle.java:71)     在   weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2433)     在   weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2281)     在   weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2259)     在   weblogic.servlet.internal.ServletRequestImpl.runInternal(ServletRequestImpl.java:1691)     在   weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.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(LivePartitionUtility.java:54)     在   weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)     在   weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:640)     在weblogic.work.ExecuteThread.execute(ExecuteThread.java:406)at   weblogic.work.ExecuteThread.run(ExecuteThread.java:346)

基于设置websocket端点的后端代码是完美的假设,并且用于尝试建立websocket连接的javascript代码是完美的。 根据信件指南,sombody可以解释为什么会出现上述错误吗?

注意:   - 根据对实际应用程序的分析,上面的堆栈跟踪已经在一个示例应用程序中被隔离,该应用程序具有一个工作的websocket端点被破坏成上述异常。

一旦你知道答案就很简单了...... 如果没有人支持正确的解决方案,我将在一天左右回答。

1 个答案:

答案 0 :(得分:3)

回答我自己的问题。

应用程序在尝试打开W​​eb套接字连接时遇到的问题与tyrus使用Sevlet 3.0规范的功能,即异步servlet处理有关。

即使在最简单的Web应用程序中,也可能会有一个过滤器适用于所有Web请求。 例如带过滤器映射的过滤器/ *。

那恰恰是问题所在。 正如以下参考文献中所解释的那样,为了允许异步servlet运行通向servlet的完整过滤器链,它们必须支持异步请求处理。

https://blogs.oracle.com/enterprisetechtips/entry/asynchronous_support_in_servlet_3

  

需要asyncSupported属性来区分编写的代码   用于同步处理的编写用于   异步上下文。实际上,对于一个应用程序来说   异步功能,整个请求处理链必须具备   通过注释或其中设置此属性   部署描述符。如果是,则抛出IllegalStateException   应用程序尝试启动异步操作,并且有一个   请求处理链中的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。

因此,总而言之,请注意您的容器可能需要异步servlet才能打开Web套接字。如果您有任何过滤器拦截对您的websocket端点的请求,您可能会对这种副作用感到惊讶。 对于来自JEE 6的应用程序尤其如此,但它很容易发生在任何全新的JEE 7应用程序中。

然而,大多数人可能没有过滤器拦截对websocket端点的调用......