2013-09-02 10 views
1

실제로 클라이언트에 데이터를 푸시하는 일부 API를 찾고 있습니다. 지금은 이것을 달성하기 위해 긴 폴링과 함께 분위기를 사용하고 있습니다. 혜성을 사용할 수있는 글래스 피쉬 3.1.2를 사용하고 있습니다.서블릿 3.0 비동기 기능 및 서버 측 푸시

나중에 Servlet 3.0의 비동기 기능에 대해 들었습니다. 그렇다면 분위기를 대체 할 수 있을지 여부를 판단하려했습니다.

요청은 요청을 받으면 응용 프로그램 범위에있는 목록에 넣을 것입니다. 그리고 나중에 무한정한 시간이 지나면 또 다른 요청을 받게되고 목록을 반복하여 클라이언트에게 응답을 보냅니다.

요청을 받고 애플리케이션 범위의 목록에 AsyncContext를 넣는 첫 번째 서블릿을 작성했습니다. 그런 다음 AsyncContext가 생성되는지 여부를 확인했습니다. 나는 실제로 URL을 때리는 아약스 전화를 썼다. ajax 요청은 30 초 후에 시간 초과/중단되었습니다. 그런 다음 나중에 AsyncContext의 시간 제한을 설정하려고 시도했으며 시간 초과가 발생하지 않도록 음수 값으로 설정했습니다. 나중에 AsyncContext의 setTimeOut (int)은 다른 목적으로 사용된다는 것을 이해했습니다. 이제 응답 시간을 보내는 데 몇 시간 또는 며칠이 걸릴지 모르겠으므로 시간 제한을 매우 거대한 것으로 설정할 수 없습니다.

그런 다음 요청 제한 시간을 일정하지 않게 설정하려고 생각했습니다. 그러나 나는 이것을 어떻게하는지 모른다.

무한한 시간 동안 요청을 일시 중단하는 resource.suspend()를 사용하여 대기에서 동일한 작업을 수행 할 수 있습니다.

이 경우 Servlet 3.0의 비동기 기능을 사용할 수 없다면 그 목적은 무엇입니까?

이 기능에 대해 이해할 수있는 것은 요청이 jdbc 연결을 말하는 일부 리소스를 기다리는 경우 요청이 대기열에 배치되고 스레드가 다시 사용할 수 있도록 스레드 풀로 반환된다는 것입니다. 다른 요청을 제공합니다. This link은 실제로 비동기 프로세스를 시작하고 오브젝트를 Runnable에 전달하고 doGet 메소드를 종료합니다. Runnable가 자원을 위해서 (때문에) 대기하고 있기 (위해) 때문에 요구를 제공하는데 시간이 걸리는 경우, thread는 thread 풀에 되 돌리고 재사용됩니다. 내 이해가 맞습니까? 내 이해가 맞으면 요청이 리소스를 기다리는 최대 시간을 초과하면 시간이 초과되고 일부 예외가 클라이언트로 전송됩니다. 프로그래밍 타임 아웃을 무기한으로 설정하고 대기없이 서버 사이드 푸시를 수행하는 방법.

많은 문서에는 비동기 서블릿을 사용하여 데이터를 클라이언트에 전달할 수 있다고 나와 있습니다. 모든 클라이언트가 긴 폴링을 사용하고 비동기가 서버에서 지원되지 않는 경우 모든 스레드마다 하나의 스레드가 할당되어 모든 스레드가 소모되고 많은 양의 메모리가 사용됩니다. 비동기가 지원되면 모든 요청이 대기열에 들어 가고 스레드는 다른 요청을 서버 할 수 있습니다. 링크 here도 마찬가지입니다. 그러나 이벤트가 수신되고 시간 초과가 될 때까지는 요청을 일시 중단 할 기술이 없습니다. 대기와 같은 프레임 워크가 어떻게 요청을 일시 중지하려고합니까? HTTP 요청을 서블릿 3.0에서 일시 중단 할 수 있다면 대기와 같은 프레임 워크가 필요 없다고 생각합니다. 서블릿 3.0 비동기 기능에 따라 요청에 스레드가 항상 첨부되지 않으므로 웹 소켓 대신 긴 폴링을 사용해도됩니다.

답변

0

나는 대답을 얻었다. 약간의 디버깅 후 대기의 suspend() 메소드는 suspend() 메소드가 http 요청을 무기한 정지시키지 않는다는 것을 알게되었다. 세션 시간 초과가 만료되어 여전히 요청이 대기 중이므로 세션 시간 초과가 만료 될 때까지 http 요청을 일시 중단합니다.

이제 분위기 프레임 워크를 대체하고 서블릿 3.0의 비동기 기능을 사용하고 싶습니다.

클라이언트가 요청을 보냅니다. 내 서블릿에서 asyncStart (req, res)를 시작한 다음 세션 시간 초과에 대한 시간 초과를 설정합니다. 한편 이벤트가 발생하면 Runnable에서 응답을 커밋합니다. 그런 다음 클라이언트가 다른 요청을합니다.

여기에 그럼 난 옵저버 패턴을 사용하여 내 자신의 이벤트 버스를 만듭니다 내 샘플 코드

AsyncContext actxt = request.startAsync(request, response); 
actxt.setTimeout(request.getMaxInactiveInterval()); 
executor.execute(new MyService(actxt)); 

입니다. MyService 클래스는 이벤트 핸들러를 구현합니다. 언젠가 나중에 이벤트가 시작되고 MySevice의 모든 인스턴스가이 이벤트를 수신하고 응답을 커밋합니다.

내 접근 방식이 옳았는지 또는 접근 방식이 개선 될 수 있는지 알려주세요.