2017-01-20 9 views
0

WebSocket 지원을위한 프레임 워크로 Atmosphere를 사용하는 채팅 서버를 실행합니다. 분위기는 저지를 사용합니다. 왜냐하면 저의 저지 메 빈 종속성을 사용하기 때문입니다.Tomcat 8 및 비 대기자 클라이언트의 분위기 + 저지 오류

채팅 서버는 톰캣 7에서 실행되며 우리는 톰캣 8로 고객의

한 자신의 자바 웹 소켓 API로 타이 러스를 사용하여 업그레이드된다.

채팅 서버를 Tomcat 7 (Java 6,7 ​​또는 8)에 배포하면 문제가 없습니다.

Tomcat 8 (Java 8)의 채팅 서버에서 Atmosphere를 사용하는 테스트 클라이언트가 제대로 작동하지만 Tyrus를 사용하는 클라이언트는 제대로 작동하지 않습니다. 우리가 볼 수있는 오류는 다음과 같습니다 ": // localhost를 : 8080/채팅/HTTP는"(요청이 이루어 톰캣 (7)과 함께 웹 소켓 요청에서 요청 URL과 유사한 볼 수 있기 때문에

2017-01-17 02:36:51,114 ERROR() [http-nio-8443-exec-11] ReflectorServletProcessor (?) - onRequest() 
java.lang.IllegalArgumentException: Schema specific part is opaque 
     at com.sun.jersey.api.uri.UriBuilderImpl.checkSsp(UriBuilderImpl.java:529) 
     at com.sun.jersey.api.uri.UriBuilderImpl.replacePath(UriBuilderImpl.java:256) 
     at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:703) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 
     at org.atmosphere.util.AtmosphereFilterChain.doFilter(AtmosphereFilterChain.java:135) 
     at org.atmosphere.util.AtmosphereFilterChain.invokeFilterChain(AtmosphereFilterChain.java:96) 
     at org.atmosphere.handler.ReflectorServletProcessor$FilterChainServletWrapper.service(ReflectorServletProcessor.java:317) 
     at org.atmosphere.handler.ReflectorServletProcessor.onRequest(ReflectorServletProcessor.java:160) 
     at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:199) 
     at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:107) 
     at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:66) 
     at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:2078) 
     at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:571) 
     at org.atmosphere.websocket.DefaultWebSocketProcessor$3.run(DefaultWebSocketProcessor.java:333) 
     at org.atmosphere.util.VoidExecutorService.execute(VoidExecutorService.java:101) 
     at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:328) 
     at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.java:525) 
     at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.java:428) 
     at org.atmosphere.container.JSR356Endpoint$1.onMessage(JSR356Endpoint.java:213) 
     at org.atmosphere.container.JSR356Endpoint$1.onMessage(JSR356Endpoint.java:210) 
     at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:393) 
     at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:494) 
     at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:289) 
     at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:130) 
     at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:60) 
     at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:183) 
     at org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198) 
     at org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96) 
     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:669) 
     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) 
     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
     at java.lang.Thread.run(Thread.java:745) 

이 발생 ~ ws : // localhost : 8080/chat /하지만 http : // somewhere로 변경되었습니다.) 그러나 Tomcat 8의 경우 websocket 요청의 요청 URL은 "/ chat /"과 비슷하며 스키마는 존재하지 않으며 Jersey는 오류를 발생시킵니다.

이 문제를 해결하기 위해 Atmosphere는 대기 클라이언트가 요청할 때 스키마가있는 헤더 "origin"을 찾습니다. 그러나 Tyrus 클라이언트가 요청할 때 "origin"헤더에 위에 표시된 오류가 발생하는 http 스키마가 포함되어 있지 않습니다.

누구든지이 간단한 해결책에 대한 아이디어가 있거나 비슷한 문제가 있는지 궁금합니다. 나는 간단한 해결책을 찾기 위해 많은 노력을했지만 아직 그것을 찾지 못했습니다. 하나도 없으면 Atmosphere 사용을 중단하고 많은 코드 리팩토링을 사용하는 다른 작업을해야합니다.

다음은이 문제를 해결할 수있는 티켓/버그에 대한 링크입니다.이 링크는 올바른 버전을 가지고 있지만 여전히 문제가 있습니다.

https://bz.apache.org/bugzilla/show_bug.cgi?id=56573 는 분위기 버전 https://github.com/Atmosphere/atmosphere/issues/1839

: 버전 1.19

타이 러스 : (분위기를 통해)

뉴저지 버전

2.4.8 이에 대한 해결 방법 "은을 변경할 1.13

답변

0

했다 origin "헤더를 필터에 추가하고 존재하지 않으면 http : // 스키마를 추가하십시오. Modify request parameter with servlet filter

import java.io.IOException; 
import java.util.Collections; 
import java.util.Enumeration; 
import javax.servlet.*; 

public class FixSchemaFilter implements Filter { 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException {} 

    @Override 
    public void destroy() {} 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     if (request instanceof HttpServletRequest) { 
      chain.doFilter(new FixSchemaHttpServletRequest((HttpServletRequest) request), response); 
     } else { 
      chain.doFilter(request, response); 
     } 
    } 

    public class FixSchemaHttpServletRequest extends HttpServletRequestWrapper { 

     public FixSchemaHttpServletRequest(HttpServletRequest request) { 
      super(request); 
     } 

     @Override 
     public String getHeader(String header) { 
      String value = super.getHeader(header); 
      if (header.equalsIgnoreCase("origin") && !value.startsWith("http://")) { 
       return "http://" + value; 
      } 
      return value; 
     } 

     @Override 
     public Enumeration getHeaders(String header) { 
      Enumeration enumeration = super.getHeaders(header); 
      if (header.equalsIgnoreCase("origin") && super.getHeader(header) != null && !super.getHeader(header).startsWith("http://")) { 
       return Collections.enumeration(Collections.singleton(getHeader(header))); 
      } 
      return enumeration; 
     } 
    } 

} 

그런 다음은 web.xml

<filter> 
     <filter-name>FixSchemaFilter</filter-name> 
     <filter-class>com.example.FixSchemaFilter</filter-class> 
</filter> 
<filter-mapping> 
     <filter-name>FixSchemaFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
</filter-mapping> 
에 필터를 추가 :이 기사는 그것을 알아내는 도왔다