2013-12-18 4 views
3

Apache CXF 2.5.1을 사용하여 Java REST (스트리밍) 서블릿을 작성하고이를 Tomcat 7.0.42 컨테이너에 전개했습니다. REST 끝점은 기본적으로 StreamingOutput의 구현이며 클라이언트 요청시 컨테이너에 전달되는 Response 개체를 래핑합니다.청크 인코딩을 사용할 때 데이터를 버퍼링하는 CXF

서비스의 성격은 센서 데이터 스트림을 클라이언트로 반환하는 것입니다. 이 스트림은 클라이언트가 연결을 끊을 때만 종료되므로 이론적으로 무한대로 길 수 있습니다. 이 문제는 센서에 의해 생성 된 데이터가 소량으로 제공 될 때 발생합니다.

서비스는 작동하지만 클라이언트가받는 데이터 응답의 크기와 관련하여 문제가 발생합니다. 클라이언트는 8192 바이트 임계 값이 서비스에 의해 손상된 후에 만 ​​데이터를 수신합니다. 그런 다음 클라이언트는 800 바이트를 수신 한 다음 8192 바이트를받은 다음 800 바이트를 수신합니다.

컨테이너가 내 구현에 전달하는 OutputStream을 플러시하는 즉시 클라이언트에 데이터를 보내고 싶습니다. StreamingOutput. 그러나, 주어진 된 OutputStream 구현 (org.apache.cxf.transport.http.AbstractHTTPDestination에 정의 된 WrappedOutputStream)에는 아무 것도 수행하지 않는 flush 메서드가 있습니다.

CXF가 사용하는 OutputStream을 제어 할 수있는 방법이 있습니까? 필요에 따라 클라이언트에 "플러시"할 수 있습니까?

답변

2

궁극적으로 요청시 버퍼를 플러시 할 수 있었던 방법은 CXF 필터, 특히 ResponseHandler의 구현을 만드는 것이 었습니다.

필자는 HttpServletResponse과 Message Implementation에서 CXF가 사용하는 OutputStream 구현 (필터 플러시를 허용하지 않는 것)을 가져 와서 FilteredOutputStream에 래핑했습니다. flush가 호출 될 때마다 HttpServletResponse에서 flush를 명시 적으로 호출합니다.

이것은 CXF에만 해당되며 이렇게하면 flush가 호출되는 빈도에 따라 훨씬 많은 오버 헤드가 발생할 수 있지만 "느린"스트리밍이 클라이언트에 더 빨리 도달 할 수 있습니다.

내가 걱정할 필요가있는 것들에 대해 의견을 말하십시오.

+1

좋은 발견! 결함을 생성하고 CXF 커뮤니티에 패치를 제공하여 어떻게 반응하는지 확인해야합니다. https://issues.apache.org/jira/browse/CXF –

1

확인할 사항은 두 가지입니다. 먼저, Content-Length 헤더 (response.setHeader())를 설정해야하며 둘째로 버퍼 크기 (response.setBufferSize())를 설정해야 할 수도 있습니다. 이이 여기에 토론을 것 같다 : 당신이 flush()을 수행 할 때

How do disable Transfer-Encoding in Tomcat 6

+0

setHeader 및 setBufferSize는 모두 Response 계약에 포함되지 않습니다. 나는 또한 덩어리를 사용하지 않으려 고하지도 않았다. 그것을 무력화시키는 것이 어떻게 도움이 될까요? 나는 chunk를 원한다고 확신한다. CXF가 flush()에 대한 나의 호출을 존중하는 OutputStream을 사용하기를 바랄 뿐이다. – harumph

+0

음 ..당신이 청킹을 할 수 있는지, 그리고 플러시를 끝까지 진행할 수 있는지 확신 할 수 없습니다. – Zeki

1

톰캣 자체가 즉시 응답을 커밋합니다. 이는 CXF의 문제점 일 수 있습니다.

제안 사항이 있다면이 응용 프로그램을 사용하기 위해 으로 전환하는 것이 좋습니다. 즉, 서버에서 클라이언트로 장기간 스트리밍하는 데 더 적합합니다. 그 반대). WebSocket이 마음에 들지 않는다면 적어도 서블릿 3.0 사양의 비동기 I/O 또는 Comet (3.0 비동기는 지원을위한 더 나은 선택 인 등)을 살펴 봐야합니다.

관련 문제