Tomcat 7でのサーブレット3非同期タスク

danny.lesnik:

非同期サポートに基づいて、サーブレット3.0とCometパターンを使用してシンプルチャットを実装しようとしています。

私はこの記事に触発されました:http : //www.javaworld.com/javaworld/jw-02-2009/jw-02-servlet3.html?page=3

私のサーブレットは次のようになります。

@WebServlet(name="chatServlet", urlPatterns={"/ChatServlet"}, asyncSupported=true)
public class ChatServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         AsyncContext aCtx = request.startAsync(request, response); 
         ServletContext appScope = request.getServletContext();    
         List<AsyncContext> watchers = (List<AsyncContext>) appScope.getAttribute("watchers");
         watchers.add(aCtx); //register the watcher
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          AsyncContext aCtx = request.startAsync(request, response); 
          ServletContext appScope = request.getServletContext(); 
          Queue<String> messages = (Queue<String>)appScope.getAttribute("messages");
          messages.add(someMessage);
    }
} 

今私のリスナーは次のようになります:

@WebListener
public class ChatPushService implements ServletContextListener {

        @Override
        public void contextInitialized(ServletContextEvent sce) {
              final List<AsyncContext> watchers = new  ArrayList<AsyncContext>();
             sce.getServletContext().setAttribute("watchers", watchers);
              // store new messages not published yet
             Queue<String> messages = new ConcurrentLinkedQueue<String>();
             sce.getServletContext().setAttribute("messages", messages);
             Executor messageExecutor = Executors.newCachedThreadPool(); 
             final Executor watcherExecutor = Executors.newCachedThreadPool();
             while(true)
              {      

                 if(!messages.isEmpty()) 
                 {
                     System.out.println("notEmpty");
                    String message =  messages.poll(); 
                    messageExecutor.execute(new Runnable(){

                        @Override
                        public void run() {
                             for(final AsyncContext aCtx : watchers){
                                 watcherExecutor.execute(new Runnable(){

                                     @Override
                                        public void run() {
                                           try {
                                            aCtx.getResponse().getWriter().print("brrrrr");
                                        } catch (IOException e) {
                                            // TODO Auto-generated catch block
                                            e.printStackTrace();
                                        }
                                     }
                                 });
                             }
                        }
                 });
              }
        }

    }
    }

私が開始しているとき、コンテナーの開始時にフリーズします。

Nov 1, 2011 1:12:09 AM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server:/usr/lib/jvm/java-6-openjdk/jre/lib/amd64:/usr/lib/jvm/java-6-openjdk/jre/../lib/amd64:/usr/java/packages/lib/amd64:/usr/lib/jni:/lib:/usr/lib
Nov 1, 2011 1:12:09 AM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:Servlet3Comet' did not find a matching property.
Nov 1, 2011 1:12:09 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Nov 1, 2011 1:12:09 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-bio-8009"]
Nov 1, 2011 1:12:09 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 624 ms
Nov 1, 2011 1:12:09 AM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Nov 1, 2011 1:12:09 AM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.22

ように見えpublic void contextInitialized機能はバックグラウンドで非同期に実行されていないと、さらにコンテナの初期化をブロックしています。

どうして?

誰かがこの問題で私を助けることができますか?

Ramesh PVK:

間違っているcontextInitialized()メソッド内でwhileループを実行していますcontextInitialized()は、アプリケーションの起動の一部としてサーブレットコンテナによって呼び出されます。whileループがあると、アプリの起動がブロックされます。

ContextListenerがウォッチャーにメッセージをパブリッシュする1つのデーモンスレッドを開始するようにコードを変更しました

@WebListener
public class ChatPushService implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
          final List<AsyncContext> watchers = new  ArrayList<AsyncContext>();
         sce.getServletContext().setAttribute("watchers", watchers);
          // store new messages not published yet
         Queue<String> messages = new ConcurrentLinkedQueue<String>();
         sce.getServletContext().setAttribute("messages", messages);
         new chatManager(sce.getServletContext()).start(); //START DAEMON

      }
}
public class ChatManager implements Runnable
{
ServletContext servletCtx;
public ChatManager(ServletContext ctx)
{
     this.servletCtx = ctx;
}
public void run()
{
         List<AsyncContext> watchers = (List<AsyncContext>) servletCtx.getAttribute("watchers");
     Queue<String> messages = (Queue<String>)appScope.getAttribute("messages");
     Executor messageExecutor = Executors.newCachedThreadPool(); 
         final Executor watcherExecutor = Executors.newCachedThreadPool();
         while(true)
          {      

             if(!messages.isEmpty()) 
             {
                 System.out.println("notEmpty");
                String message =  messages.poll(); 
                messageExecutor.execute(new Runnable(){

                    @Override
                    public void run() {
                         for(final AsyncContext aCtx : watchers){
                             watcherExecutor.execute(new Runnable(){

                                 @Override
                                    public void run() {
                                       try {
                                        aCtx.getResponse().getWriter().print("brrrrr");
                                    } catch (IOException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                    }
                                 }
                             });
                         }
                    }
             });
          }
    }

}

}

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Tomcatコネクタアーキテクチャ、スレッドプール、非同期サーブレット

分類Dev

Cometd:CometdサーブレットはTomcatで非同期をサポートしていません

分類Dev

tomcat7サーブレットのメモリリーク

分類Dev

Tomcatサーブレットルーチンで非同期HTTPクライアントを使用する方が良いですか?

分類Dev

NIOコネクタを使用してTomcatにデプロイすると、サーブレット3.0非同期を使用しますか?

分類Dev

ポストリクエスト用にTOMCAT7サーブレットでCORSを有効にする

分類Dev

サーブレット3仕様のTomcat 6

分類Dev

Tomcat に追加のサーブレット クラス パスを設定する

分類Dev

サーブレットフィルタTomcat7.0.50でのCDIインジェクション

分類Dev

サーブレットにアクセスするときに、Tomcat java.lang.NoClassDefFoundErrorの下で?

分類Dev

Javaサーブレットからの非同期タスク

分類Dev

Tomcatサーブレットアプリのバックグラウンドスレッド

分類Dev

Tomcatクラスター環境でサーブレットコンテキスト変数データを取得する

分類Dev

サーブレットからTomcatコンテキストパスへのアクセス

分類Dev

サーブレットサーブレット例外Tomcatサーブレット

分類Dev

サーブレットのマッピングとTomcatでのデプロイ

分類Dev

重大:GETの非同期タイムアウト[Spring MVC 4.3.x、Java 8、Tomcat 7を使用した巨大なデータのストリーミング]

分類Dev

サーブレットでTomcatのIPとポートを取得する

分類Dev

サーブレットは「スレッドを開始しましたが、停止できませんでした」-Tomcatのメモリリーク

分類Dev

Tomcatからサーブレットを実行するとClassNotFoundException(内部クラス)

分類Dev

Tomcat 5.5でサーブレットが見つからない

分類Dev

Tomcatサーブレットでpicocontainerを使用する

分類Dev

Tomcatで実行されているJerseyサーブレット?

分類Dev

JavaサーブレットにTomcatの404

分類Dev

TomcatサーブレットのFirebase管理SDK

分類Dev

Tomcat6でサーブレット内のApache2.4を再起動する

分類Dev

Tomcat 8の一部のパスでサーブレットが機能しない

分類Dev

Tomcat 7とJSTL

分類Dev

tomcat 7 @WebServlet

Related 関連記事

  1. 1

    Tomcatコネクタアーキテクチャ、スレッドプール、非同期サーブレット

  2. 2

    Cometd:CometdサーブレットはTomcatで非同期をサポートしていません

  3. 3

    tomcat7サーブレットのメモリリーク

  4. 4

    Tomcatサーブレットルーチンで非同期HTTPクライアントを使用する方が良いですか?

  5. 5

    NIOコネクタを使用してTomcatにデプロイすると、サーブレット3.0非同期を使用しますか?

  6. 6

    ポストリクエスト用にTOMCAT7サーブレットでCORSを有効にする

  7. 7

    サーブレット3仕様のTomcat 6

  8. 8

    Tomcat に追加のサーブレット クラス パスを設定する

  9. 9

    サーブレットフィルタTomcat7.0.50でのCDIインジェクション

  10. 10

    サーブレットにアクセスするときに、Tomcat java.lang.NoClassDefFoundErrorの下で?

  11. 11

    Javaサーブレットからの非同期タスク

  12. 12

    Tomcatサーブレットアプリのバックグラウンドスレッド

  13. 13

    Tomcatクラスター環境でサーブレットコンテキスト変数データを取得する

  14. 14

    サーブレットからTomcatコンテキストパスへのアクセス

  15. 15

    サーブレットサーブレット例外Tomcatサーブレット

  16. 16

    サーブレットのマッピングとTomcatでのデプロイ

  17. 17

    重大:GETの非同期タイムアウト[Spring MVC 4.3.x、Java 8、Tomcat 7を使用した巨大なデータのストリーミング]

  18. 18

    サーブレットでTomcatのIPとポートを取得する

  19. 19

    サーブレットは「スレッドを開始しましたが、停止できませんでした」-Tomcatのメモリリーク

  20. 20

    Tomcatからサーブレットを実行するとClassNotFoundException(内部クラス)

  21. 21

    Tomcat 5.5でサーブレットが見つからない

  22. 22

    Tomcatサーブレットでpicocontainerを使用する

  23. 23

    Tomcatで実行されているJerseyサーブレット?

  24. 24

    JavaサーブレットにTomcatの404

  25. 25

    TomcatサーブレットのFirebase管理SDK

  26. 26

    Tomcat6でサーブレット内のApache2.4を再起動する

  27. 27

    Tomcat 8の一部のパスでサーブレットが機能しない

  28. 28

    Tomcat 7とJSTL

  29. 29

    tomcat 7 @WebServlet

ホットタグ

アーカイブ