Tôi đang cố gắng triển khai Trò chuyện đơn giản bằng Servlet 3.0 và mẫu Comet dựa trên hỗ trợ không đồng bộ của nó.Servlet 3 Nhiệm vụ không đồng bộ trên Tomcat 7
Tôi lấy cảm hứng từ bài viết này: http://www.javaworld.com/javaworld/jw-02-2009/jw-02-servlet3.html?page=3
servlet của tôi trông như thế này.
@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);
}
}
tại Listener của tôi trông như thế này:
@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();
}
}
});
}
}
});
}
}
}
}
Khi tôi bắt đầu đóng băng của tôi nó trong thời gian khởi container.
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
Có vẻ như chức năng public void contextInitialized
không chạy không đồng bộ trên nền và đang chặn việc khởi tạo vùng chứa tiếp theo.
Tại sao?
ai cũng có thể giúp tôi về vấn đề này?
Phần đó cũng làm tôi ngạc nhiên, nhưng mã đó được trình bày như vậy trong bài viết của Javaworld mà OP đã sao chép, vì vậy OP không phải là nguyên nhân gây ra ở đây. – BalusC
Tôi đang cố gắng tạo trò chuyện trong đó mỗi tin nhắn được gửi bởi POST sẽ được gửi đến tất cả khách hàng Đã đăng ký ở đó, Vì vậy, loại hàng đợi được tạo và trong khi (true) chặn màn hình nếu thông báo mới này đã có trong hàng đợi. –