Servlet 3 Async task Tomcat 7
Ich versuche es zu implementieren, Einfach chat mit Servlet 3.0 und Comet-Muster basierend auf seiner async-Unterstützung.
Ich bin inspiriert von diesem Artikel:
http://www.javaworld.com/javaworld/jw-02-2009/jw-02-servlet3.html?page=3
Mein servlet sieht wie folgt aus.
@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);
}
}
nun meine Listener sieht so aus:
@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();
}
}
});
}
}
});
}
}
}
}
Wenn ich anfange, meine friert es bei container-initiation.
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
Sieht es aus wie public void contextInitialized
- Funktion nicht ausgeführt wird asynchron im hintergrund und blockiert weitere container-Initialisierung.
Warum?
kann jemand mir helfen, dieses Problem?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ausgeführt werden while-Schleife innerhalb contextInitialized() Methode, die falsch ist. contextInitialized() ist aufgerufen, durch Servlet-Container als Teil des beim starten der Anwendung, mit while-Schleife wird es sperren Sie Ihre app starten.
Modifiziert den code der ContextListener startet einen daemon-thread veröffentlicht die Nachrichten an die Beobachter
Kann ich nicht kommentieren, Ramesh s-code, also ich habe, um es hier zu platzieren...
Da kein thread wraps Runde der ChatManager lauffähig ist, glaube ich, sollten Sie anrufen run() auf und nicht die start(). Auch Recht offensichtlich, obwohl, es sollte neue ChatManager()..nicht neu chatManager()...account von Java wurde groß-und Kleinschreibung.